Data Exploration and Wrangling
The first step in performing any data analysis is to explore the data.
For example, we might want to better understand the variables included in the data, as we may learn about important details about the data that we should keep in mind as we try to predict our outcome variable.
First, let’s just get a general sense of our data. We can do that using the glimpse() function of the dplyr package (it is also in the tibble package).
We will also use the %>% pipe, which can be used to define the input for later sequential steps.
This will make more sense when we have multiple sequential steps using the same data object.
To use the pipe notation we need to install and load dplyr as well.
For example, here we start with pm data object and “pipe” the object into as input into the glimpse() function. The output is is an overview of what is in the pm object such as the number of rows and columns, all the column names, the data types for each column and the first view values in each column. The output below is scrollable so you can see everything from the glimpse() function.
Rows: 876
Columns: 50
$ id <dbl> 1003.001, 1027.000, 1033.100, 1049.100, 1…
$ value <dbl> 9.597647, 10.800000, 11.212174, 11.659091…
$ fips <dbl> 1003, 1027, 1033, 1049, 1055, 1069, 1073,…
$ lat <dbl> 30.49800, 33.28126, 34.75878, 34.28763, 3…
$ lon <dbl> -87.88141, -85.80218, -87.65056, -85.9683…
$ state <chr> "Alabama", "Alabama", "Alabama", "Alabama…
$ county <chr> "Baldwin", "Clay", "Colbert", "DeKalb", "…
$ city <chr> "Fairhope", "Ashland", "Muscle Shoals", "…
$ CMAQ <dbl> 8.098836, 9.766208, 9.402679, 8.534772, 9…
$ zcta <dbl> 36532, 36251, 35660, 35962, 35901, 36303,…
$ zcta_area <dbl> 190980522, 374132430, 16716984, 203836235…
$ zcta_pop <dbl> 27829, 5103, 9042, 8300, 20045, 30217, 90…
$ imp_a500 <dbl> 0.01730104, 1.96972318, 19.17301038, 5.78…
$ imp_a1000 <dbl> 1.4096021, 0.8531574, 11.1448962, 3.86764…
$ imp_a5000 <dbl> 3.3360118, 0.9851479, 15.1786154, 1.23114…
$ imp_a10000 <dbl> 1.9879187, 0.5208189, 9.7253870, 1.031646…
$ imp_a15000 <dbl> 1.4386207, 0.3359198, 5.2472094, 0.973044…
$ county_area <dbl> 4117521611, 1564252280, 1534877333, 20126…
$ county_pop <dbl> 182265, 13932, 54428, 71109, 104430, 1015…
$ log_dist_to_prisec <dbl> 4.648181, 7.219907, 5.760131, 3.721489, 5…
$ log_pri_length_5000 <dbl> 8.517193, 8.517193, 8.517193, 8.517193, 9…
$ log_pri_length_10000 <dbl> 9.210340, 9.210340, 9.274303, 10.409411, …
$ log_pri_length_15000 <dbl> 9.630228, 9.615805, 9.658899, 11.173626, …
$ log_pri_length_25000 <dbl> 11.32735, 10.12663, 10.15769, 11.90959, 1…
$ log_prisec_length_500 <dbl> 7.295356, 6.214608, 8.611945, 7.310155, 8…
$ log_prisec_length_1000 <dbl> 8.195119, 7.600902, 9.735569, 8.585843, 9…
$ log_prisec_length_5000 <dbl> 10.815042, 10.170878, 11.770407, 10.21420…
$ log_prisec_length_10000 <dbl> 11.88680, 11.40554, 12.84066, 11.50894, 1…
$ log_prisec_length_15000 <dbl> 12.205723, 12.042963, 13.282656, 12.35366…
$ log_prisec_length_25000 <dbl> 13.41395, 12.79980, 13.79973, 13.55979, 1…
$ log_nei_2008_pm25_sum_10000 <dbl> 0.318035438, 3.218632928, 6.573127301, 0.…
$ log_nei_2008_pm25_sum_15000 <dbl> 1.967358961, 3.218632928, 6.581917457, 3.…
$ log_nei_2008_pm25_sum_25000 <dbl> 5.067308, 3.218633, 6.875900, 4.887665, 4…
$ log_nei_2008_pm10_sum_10000 <dbl> 1.35588511, 3.31111648, 6.69187313, 0.000…
$ log_nei_2008_pm10_sum_15000 <dbl> 2.26783411, 3.31111648, 6.70127741, 3.350…
$ log_nei_2008_pm10_sum_25000 <dbl> 5.628728, 3.311116, 7.148858, 5.171920, 4…
$ popdens_county <dbl> 44.265706, 8.906492, 35.460814, 35.330814…
$ popdens_zcta <dbl> 145.716431, 13.639555, 540.887040, 40.718…
$ nohs <dbl> 3.3, 11.6, 7.3, 14.3, 4.3, 5.8, 7.1, 2.7,…
$ somehs <dbl> 4.9, 19.1, 15.8, 16.7, 13.3, 11.6, 17.1, …
$ hs <dbl> 25.1, 33.9, 30.6, 35.0, 27.8, 29.8, 37.2,…
$ somecollege <dbl> 19.7, 18.8, 20.9, 14.9, 29.2, 21.4, 23.5,…
$ associate <dbl> 8.2, 8.0, 7.6, 5.5, 10.1, 7.9, 7.3, 8.0, …
$ bachelor <dbl> 25.3, 5.5, 12.7, 7.9, 10.0, 13.7, 5.9, 17…
$ grad <dbl> 13.5, 3.1, 5.1, 5.8, 5.4, 9.8, 2.0, 8.7, …
$ pov <dbl> 6.1, 19.5, 19.0, 13.8, 8.8, 15.6, 25.5, 7…
$ hs_orless <dbl> 33.3, 64.6, 53.7, 66.0, 45.4, 47.2, 61.4,…
$ urc2013 <dbl> 4, 6, 4, 6, 4, 4, 1, 1, 1, 1, 1, 1, 1, 2,…
$ urc2006 <dbl> 5, 6, 4, 5, 4, 4, 1, 1, 1, 1, 1, 1, 1, 2,…
$ aod <dbl> 37.36364, 34.81818, 36.00000, 33.08333, 4…
We can see that there are 876 monitors (rows) and that we have 50 total variables (columns) - one of which is the outcome variable. In this case, the outcome variable is called value.
AVOCADO: Should we link to a code book here? Like could we use this as a teaching opportunity to demonstrate the purpose of a code book so a student knows how we know the PM values are value?
avocado response: there isnt a code book related to this data, Roger wrangled it for me, but the vaping case study actually uses code books for that data. Would you like to link to a generic code book and describe that process? I did however add information about Roger and how he previously collected the data.
Notice that some of the variables that we would think of as factors (or categorical data) are currently of class character as indicated by the <chr> just to the right of the column names/variable names in the glimpse() output. This means that the variable values are character strings, such as words or phrases.
The other variables are of class <dbl>, which stands for double precision which indicates that the are numeric and that they have decimal values. In contrast, one could have integer values which would not allow for decimal numbers. Here is a link for more information on double precision numeric values.
Another common data class is factor which is abbreviated like this: <fct>. A factor is something that has unique levels but there is no appreciable order to the levels. For example we can have a numeric value that is just an id that we want to be interpreted as just a unique level and not as the number that it would typically indicate. This would be useful for several of our variables:
- the monitor ID (
id)
- the Federal Information Processing Standard number for the county where the monitor was located (
fips)
- the zip code tabulation area (
zcta)
None of the values actually have any real numeric meaning, so we want to make sure that R does not interpret them as if they do.
So let’s convert these variables into factors. We can do this using the across() function of the dplyr package and the as.factor() base function. The across() function has two main arguments: (i) the columns you want to operate on and (ii) the function or list of functions to apply to each column.
In this case, we are also using the magrittr assignment pipe or double pipe that looks like this %<>% of the magrittr package. This allows us use the pm data as input, but also reassigns the output to the same data object name.
Rows: 876
Columns: 50
$ id <fct> 1003.001, 1027.0001, 1033.1002, 1049.1003…
$ value <dbl> 9.597647, 10.800000, 11.212174, 11.659091…
$ fips <fct> 1003, 1027, 1033, 1049, 1055, 1069, 1073,…
$ lat <dbl> 30.49800, 33.28126, 34.75878, 34.28763, 3…
$ lon <dbl> -87.88141, -85.80218, -87.65056, -85.9683…
$ state <chr> "Alabama", "Alabama", "Alabama", "Alabama…
$ county <chr> "Baldwin", "Clay", "Colbert", "DeKalb", "…
$ city <chr> "Fairhope", "Ashland", "Muscle Shoals", "…
$ CMAQ <dbl> 8.098836, 9.766208, 9.402679, 8.534772, 9…
$ zcta <fct> 36532, 36251, 35660, 35962, 35901, 36303,…
$ zcta_area <dbl> 190980522, 374132430, 16716984, 203836235…
$ zcta_pop <dbl> 27829, 5103, 9042, 8300, 20045, 30217, 90…
$ imp_a500 <dbl> 0.01730104, 1.96972318, 19.17301038, 5.78…
$ imp_a1000 <dbl> 1.4096021, 0.8531574, 11.1448962, 3.86764…
$ imp_a5000 <dbl> 3.3360118, 0.9851479, 15.1786154, 1.23114…
$ imp_a10000 <dbl> 1.9879187, 0.5208189, 9.7253870, 1.031646…
$ imp_a15000 <dbl> 1.4386207, 0.3359198, 5.2472094, 0.973044…
$ county_area <dbl> 4117521611, 1564252280, 1534877333, 20126…
$ county_pop <dbl> 182265, 13932, 54428, 71109, 104430, 1015…
$ log_dist_to_prisec <dbl> 4.648181, 7.219907, 5.760131, 3.721489, 5…
$ log_pri_length_5000 <dbl> 8.517193, 8.517193, 8.517193, 8.517193, 9…
$ log_pri_length_10000 <dbl> 9.210340, 9.210340, 9.274303, 10.409411, …
$ log_pri_length_15000 <dbl> 9.630228, 9.615805, 9.658899, 11.173626, …
$ log_pri_length_25000 <dbl> 11.32735, 10.12663, 10.15769, 11.90959, 1…
$ log_prisec_length_500 <dbl> 7.295356, 6.214608, 8.611945, 7.310155, 8…
$ log_prisec_length_1000 <dbl> 8.195119, 7.600902, 9.735569, 8.585843, 9…
$ log_prisec_length_5000 <dbl> 10.815042, 10.170878, 11.770407, 10.21420…
$ log_prisec_length_10000 <dbl> 11.88680, 11.40554, 12.84066, 11.50894, 1…
$ log_prisec_length_15000 <dbl> 12.205723, 12.042963, 13.282656, 12.35366…
$ log_prisec_length_25000 <dbl> 13.41395, 12.79980, 13.79973, 13.55979, 1…
$ log_nei_2008_pm25_sum_10000 <dbl> 0.318035438, 3.218632928, 6.573127301, 0.…
$ log_nei_2008_pm25_sum_15000 <dbl> 1.967358961, 3.218632928, 6.581917457, 3.…
$ log_nei_2008_pm25_sum_25000 <dbl> 5.067308, 3.218633, 6.875900, 4.887665, 4…
$ log_nei_2008_pm10_sum_10000 <dbl> 1.35588511, 3.31111648, 6.69187313, 0.000…
$ log_nei_2008_pm10_sum_15000 <dbl> 2.26783411, 3.31111648, 6.70127741, 3.350…
$ log_nei_2008_pm10_sum_25000 <dbl> 5.628728, 3.311116, 7.148858, 5.171920, 4…
$ popdens_county <dbl> 44.265706, 8.906492, 35.460814, 35.330814…
$ popdens_zcta <dbl> 145.716431, 13.639555, 540.887040, 40.718…
$ nohs <dbl> 3.3, 11.6, 7.3, 14.3, 4.3, 5.8, 7.1, 2.7,…
$ somehs <dbl> 4.9, 19.1, 15.8, 16.7, 13.3, 11.6, 17.1, …
$ hs <dbl> 25.1, 33.9, 30.6, 35.0, 27.8, 29.8, 37.2,…
$ somecollege <dbl> 19.7, 18.8, 20.9, 14.9, 29.2, 21.4, 23.5,…
$ associate <dbl> 8.2, 8.0, 7.6, 5.5, 10.1, 7.9, 7.3, 8.0, …
$ bachelor <dbl> 25.3, 5.5, 12.7, 7.9, 10.0, 13.7, 5.9, 17…
$ grad <dbl> 13.5, 3.1, 5.1, 5.8, 5.4, 9.8, 2.0, 8.7, …
$ pov <dbl> 6.1, 19.5, 19.0, 13.8, 8.8, 15.6, 25.5, 7…
$ hs_orless <dbl> 33.3, 64.6, 53.7, 66.0, 45.4, 47.2, 61.4,…
$ urc2013 <dbl> 4, 6, 4, 6, 4, 4, 1, 1, 1, 1, 1, 1, 1, 2,…
$ urc2006 <dbl> 5, 6, 4, 5, 4, 4, 1, 1, 1, 1, 1, 1, 1, 2,…
$ aod <dbl> 37.36364, 34.81818, 36.00000, 33.08333, 4…
Great! Now we can see that these variables are now factors as indicated by <fct> after the variable name.
Skim package
The skim() function of the skimr package is also really helpful for getting a general sense of your data. By design, it provides summary statistics about variables in the data set.
Notice how there is a column called n_missing about the number of values that are missing.
This is also indicated by the complete_rate variable (or missing/number of observations).
In our data set, it looks like our data do not contain any missing data.
Also notice how the function provides separate tables of summary statistics for each data type: character, factor and numeric.
Next, the n_unqiue column shows us the number of unique values for each of our columns. We can see that there are 49 states represented in the data.
We can see that for many variables there are many low values as the distribution shows two peaks, one near zero and another with a higher value.
This is true for the imp variables (measures of development), the nei variables (measures of emission sources) and the road density variables.
We can also see that the range of some of the variables is very large, in particular the area and population related variables.
Let’s take a look to see which states are included using the distinct() function of the dplyr package:
Scroll through the output:
It looks like “District of Columbia” is being included as a state. We can see that Alaska and Hawaii are not included in the data.
Evaluate correlation
In prediction analyses, it is also useful to evaluate if any of the variables are correlated. Why should we care about this?
If we are using a linear regression to model our data then we might run into a problem called multicolinearity which can lead us to misinterpret what is really predictive of our outcome variable. This phenomenon occurs when the predictor variables actually predict one another. See this case study for a deeper explanation about this.
Another reason we should look out for correlation is that we don’t want to include redundant variables. This can add unnecessary noise to our algorithm causing a reduction in prediction accuracy and it can cause our algorithm to be unnecessarily slower. Finally, it can also make it difficult to interpret what variables are actually predictive.
Intuitively we can expect some of our variables to be correlated.
Let’s first take a look at all of our numeric variables with thecorrplot package: The corrplot package is another option to look at correlation among possible predictors, and particularly useful if we have many predictors.
First, we calculate the Pearson correlation coefficients between all features pairwise using the cor() function of the stats package (which is loaded automatically). Then we use the corrplot::corrplot() function.
The tl.cex = 0.5 argument controls the size of the text label.
We can also plot the absolute value of the Pearson correlation coefficients using the abs() function from base R and change the order of the columns.

There are several options for ordering the variables. See here for more options. Here we will use the “hclust” option for ordering by hierarchical clustering - which will order the variables by how similar they are to one another.
The cl.lim = c(0, 1) argument limits the color label to be between 0 and 1.
We can see that the development variables (imp) variables are correlated with each other as we might expect. We also see that the road density variables seem to be correlated with each other, and the emission variables seem to be correlated with each other.
Also notice that none of the predictors are highly correlated with our outcome variable (value).
We can take also take a closer look using the ggcorr() function and the ggpairs() function of the GGally package.
To select our variables of interest we can use the select() function with the contains() function of the tidyr package.
First let’s look at the imp/development variables. We can change the default color palette (palette = "RdBu") and add on correlation coefficients to the plot (label = TRUE).


Indeed, we can see that imp_a1000 and imp_a500 are highly correlated, as well as imp_a10000, imp_a15000.
Next, let’s take a look at the road density data:

We can see that many of the road density variables are highly correlated with one another, while others are less so.
Finally let’s look at the emission variables.


We would also expect the population density data might correlate with some of these variables. Let’s take a look.


Interesting, so these variables don’t appear to be highly correlated, therefore we might need variables from each of the categories to predict our monitor PM2.5 pollution values.
Because some variables in our data have extreme values, it might be good to take a log transformation. This can affect our estimates of correlation.


Indeed this increased the correlation, but variables from each of these categories may still prove to be useful for prediction.
Now that we have a sense of what our data are, we can get started with building a machine learning model to predict air pollution.
Data Visualization
Our main question for this case study was:
Can we predict annual average air pollution concentrations at the granularity of zip code regional levels using predictors such as data about population density, urbanization, road density, as well as, satellite pollution data and chemical modeling data?
Thus far, we have build a machine learning (ML) model to predict fine particulate matter air pollution levels based on our predictor variables (or features).
Now, let’s make a plot of our predicted outcome values (\(\hat{Y}\)) and actual outcome values \(Y\) we observed.
First, let’s start by making a plot of our monitors. To do this, we will use the following packages to create a map of the US:
sf - the simple features package helps to convert geographical coordinates into geometry variables which are useful for making 2D plots
maps - this package contains geographical outlines and plotting functions to create plots with maps
rnaturalearth- this allows for easy interaction with map data from Natural Earth which is a public domain map dataset
rgeos - this package interfaces with the Geometry Engine-Open Source (GEOS) which is also helpful for coordinate conversion
We will start with getting an outline of the US with the ne_countries() function of the rnaturalearth package which will return polygons of the countries in the Natural Earth dataset.
AVOCADO: So I definitely have the rnaturalearthdata package installed, but for someone reason every time I go to run the code below it says that I need to install the package. Just curious – what version of R are you using?avocado response - the end of the case study shows this.. hopefully this works now :/ please let me know and I will figure it out
Rows: 241
Columns: 64
$ scalerank <int> 3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 3, 1, 5, 3, 1, 1, 1, 1, 1, 1…
$ featurecla <chr> "Admin-0 country", "Admin-0 country", "Admin-0 country", "…
$ labelrank <dbl> 5, 3, 3, 6, 6, 6, 6, 4, 2, 6, 4, 4, 5, 6, 6, 2, 4, 5, 6, 2…
$ sovereignt <chr> "Netherlands", "Afghanistan", "Angola", "United Kingdom", …
$ sov_a3 <chr> "NL1", "AFG", "AGO", "GB1", "ALB", "FI1", "AND", "ARE", "A…
$ adm0_dif <dbl> 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0…
$ level <dbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2…
$ type <chr> "Country", "Sovereign country", "Sovereign country", "Depe…
$ admin <chr> "Aruba", "Afghanistan", "Angola", "Anguilla", "Albania", "…
$ adm0_a3 <chr> "ABW", "AFG", "AGO", "AIA", "ALB", "ALD", "AND", "ARE", "A…
$ geou_dif <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
$ geounit <chr> "Aruba", "Afghanistan", "Angola", "Anguilla", "Albania", "…
$ gu_a3 <chr> "ABW", "AFG", "AGO", "AIA", "ALB", "ALD", "AND", "ARE", "A…
$ su_dif <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
$ subunit <chr> "Aruba", "Afghanistan", "Angola", "Anguilla", "Albania", "…
$ su_a3 <chr> "ABW", "AFG", "AGO", "AIA", "ALB", "ALD", "AND", "ARE", "A…
$ brk_diff <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
$ name <chr> "Aruba", "Afghanistan", "Angola", "Anguilla", "Albania", "…
$ name_long <chr> "Aruba", "Afghanistan", "Angola", "Anguilla", "Albania", "…
$ brk_a3 <chr> "ABW", "AFG", "AGO", "AIA", "ALB", "ALD", "AND", "ARE", "A…
$ brk_name <chr> "Aruba", "Afghanistan", "Angola", "Anguilla", "Albania", "…
$ brk_group <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ abbrev <chr> "Aruba", "Afg.", "Ang.", "Ang.", "Alb.", "Aland", "And.", …
$ postal <chr> "AW", "AF", "AO", "AI", "AL", "AI", "AND", "AE", "AR", "AR…
$ formal_en <chr> "Aruba", "Islamic State of Afghanistan", "People's Republi…
$ formal_fr <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ note_adm0 <chr> "Neth.", NA, NA, "U.K.", NA, "Fin.", NA, NA, NA, NA, "U.S.…
$ note_brk <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "Multiple clai…
$ name_sort <chr> "Aruba", "Afghanistan", "Angola", "Anguilla", "Albania", "…
$ name_alt <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ mapcolor7 <dbl> 4, 5, 3, 6, 1, 4, 1, 2, 3, 3, 4, 4, 1, 7, 2, 1, 3, 1, 2, 3…
$ mapcolor8 <dbl> 2, 6, 2, 6, 4, 1, 4, 1, 1, 1, 5, 5, 2, 5, 2, 2, 1, 6, 2, 2…
$ mapcolor9 <dbl> 2, 8, 6, 6, 1, 4, 1, 3, 3, 2, 1, 1, 2, 9, 5, 2, 3, 5, 5, 1…
$ mapcolor13 <dbl> 9, 7, 1, 3, 6, 6, 8, 3, 13, 10, 1, NA, 7, 11, 5, 7, 4, 8, …
$ pop_est <dbl> 103065, 28400000, 12799293, 14436, 3639453, 27153, 83888, …
$ gdp_md_est <dbl> 2258.0, 22270.0, 110300.0, 108.9, 21810.0, 1563.0, 3660.0,…
$ pop_year <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ lastcensus <dbl> 2010, 1979, 1970, NA, 2001, NA, 1989, 2010, 2010, 2001, 20…
$ gdp_year <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ economy <chr> "6. Developing region", "7. Least developed region", "7. L…
$ income_grp <chr> "2. High income: nonOECD", "5. Low income", "3. Upper midd…
$ wikipedia <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ fips_10 <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ iso_a2 <chr> "AW", "AF", "AO", "AI", "AL", "AX", "AD", "AE", "AR", "AM"…
$ iso_a3 <chr> "ABW", "AFG", "AGO", "AIA", "ALB", "ALA", "AND", "ARE", "A…
$ iso_n3 <chr> "533", "004", "024", "660", "008", "248", "020", "784", "0…
$ un_a3 <chr> "533", "004", "024", "660", "008", "248", "020", "784", "0…
$ wb_a2 <chr> "AW", "AF", "AO", NA, "AL", NA, "AD", "AE", "AR", "AM", "A…
$ wb_a3 <chr> "ABW", "AFG", "AGO", NA, "ALB", NA, "ADO", "ARE", "ARG", "…
$ woe_id <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ adm0_a3_is <chr> "ABW", "AFG", "AGO", "AIA", "ALB", "ALA", "AND", "ARE", "A…
$ adm0_a3_us <chr> "ABW", "AFG", "AGO", "AIA", "ALB", "ALD", "AND", "ARE", "A…
$ adm0_a3_un <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ adm0_a3_wb <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ continent <chr> "North America", "Asia", "Africa", "North America", "Europ…
$ region_un <chr> "Americas", "Asia", "Africa", "Americas", "Europe", "Europ…
$ subregion <chr> "Caribbean", "Southern Asia", "Middle Africa", "Caribbean"…
$ region_wb <chr> "Latin America & Caribbean", "South Asia", "Sub-Saharan Af…
$ name_len <dbl> 5, 11, 6, 8, 7, 5, 7, 20, 9, 7, 14, 10, 23, 22, 17, 9, 7, …
$ long_len <dbl> 5, 11, 6, 8, 7, 13, 7, 20, 9, 7, 14, 10, 27, 35, 19, 9, 7,…
$ abbrev_len <dbl> 5, 4, 4, 4, 4, 5, 4, 6, 4, 4, 9, 4, 7, 10, 6, 4, 5, 4, 4, …
$ tiny <dbl> 4, NA, NA, NA, NA, 5, 5, NA, NA, NA, 3, NA, NA, 2, 4, NA, …
$ homepart <dbl> NA, 1, 1, NA, 1, NA, 1, 1, 1, 1, NA, 1, NA, NA, 1, 1, 1, 1…
$ geometry <MULTIPOLYGON [°]> MULTIPOLYGON (((-69.89912 1..., MULTIPOLYGON …
Here you can see the data about the countries in the world. Notice the geometry variable. This is used to create the outlines that we want.
Now we can use the geom_sf() function of the ggplot2 package to create a visual of simple feature (the geometry coordinates found in the geometry variable).

So now we can see that we have outlines of all the countries in the world.
We want to limit this just to the coordinates for the US. We will do this based on the coordinates we found on Wikipedia. According to this link, these are the latitude and longitude bounds of the continental US:
- top = 49.3457868 # north lat
- left = -124.7844079 # west long
- right = -66.9513812 # east long
- bottom = 24.7433195 # south lat
Now we just have a plot that is mostly limited to the outline of the US.
Now we will use the geom_point() function of the ggplot package to add scatter plot on top of the map. We want to show where the monitors are located based on the latitude and longitude values in the data.
Nice!
Now let’s add county lines.
County graphical data is available from the maps package. The sf package which again is short for simple features creates a data frame about this graphical data so that we can work with it.
Simple feature collection with 3076 features and 1 field
geometry type: MULTIPOLYGON
dimension: XY
bbox: xmin: -124.6813 ymin: 25.12993 xmax: -67.00742 ymax: 49.38323
CRS: EPSG:4326
First 10 features:
ID geom
1 alabama,autauga MULTIPOLYGON (((-86.50517 3...
2 alabama,baldwin MULTIPOLYGON (((-87.93757 3...
3 alabama,barbour MULTIPOLYGON (((-85.42801 3...
4 alabama,bibb MULTIPOLYGON (((-87.02083 3...
5 alabama,blount MULTIPOLYGON (((-86.9578 33...
6 alabama,bullock MULTIPOLYGON (((-85.66866 3...
7 alabama,butler MULTIPOLYGON (((-86.8604 31...
8 alabama,calhoun MULTIPOLYGON (((-85.74313 3...
9 alabama,chambers MULTIPOLYGON (((-85.59416 3...
10 alabama,cherokee MULTIPOLYGON (((-85.46812 3...
Now we will use this data within the geom_sf() function to add this to our plot. We will also add a title using the ggtitle() function, as well as remove axis ticks and titles using the theme() function of the ggplot2 package.
monitors <- ggplot(data = world) +
geom_sf(data = counties, fill = NA, color = gray(.5))+
coord_sf(xlim = c(-125, -66), ylim = c(24.5, 50),
expand = FALSE) +
geom_point(data = pm, aes(x = lon, y = lat), size = 2,
shape = 23, fill = "darkred") +
ggtitle("Monitor Locations") +
theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank(),
axis.title.y=element_blank(),
axis.text.y=element_blank(),
axis.ticks.y=element_blank())
monitors

Great!
Now, let’s add a fill at the county-level for the true monitor values of air pollution.
First, we need to get the county map data that we just got and our air pollution data to have similarly formatted county names so that we can combine the datasets together.
We can see that in the county data the counties are listed after the state name and a comma. In addition they are all lower case.
Simple feature collection with 6 features and 1 field
geometry type: MULTIPOLYGON
dimension: XY
bbox: xmin: -88.01778 ymin: 30.24071 xmax: -85.06131 ymax: 34.2686
CRS: EPSG:4326
ID geom
1 alabama,autauga MULTIPOLYGON (((-86.50517 3...
2 alabama,baldwin MULTIPOLYGON (((-87.93757 3...
3 alabama,barbour MULTIPOLYGON (((-85.42801 3...
4 alabama,bibb MULTIPOLYGON (((-87.02083 3...
5 alabama,blount MULTIPOLYGON (((-86.9578 33...
6 alabama,bullock MULTIPOLYGON (((-85.66866 3...
In contrast, our air pollution pm data shows counties as titles with the first letter as upper case.
[1] "Baldwin" "Clay" "Colbert" "DeKalb" "Etowah" "Houston"
We can use the separate() function of the tidyr package to separate the ID variable of our counties data into two variables based on the comma as a separator.
Simple feature collection with 6 features and 2 fields
geometry type: MULTIPOLYGON
dimension: XY
bbox: xmin: -88.01778 ymin: 30.24071 xmax: -85.06131 ymax: 34.2686
CRS: EPSG:4326
state county geom
1 alabama autauga MULTIPOLYGON (((-86.50517 3...
2 alabama baldwin MULTIPOLYGON (((-87.93757 3...
3 alabama barbour MULTIPOLYGON (((-85.42801 3...
4 alabama bibb MULTIPOLYGON (((-87.02083 3...
5 alabama blount MULTIPOLYGON (((-86.9578 33...
6 alabama bullock MULTIPOLYGON (((-85.66866 3...
Now we just need to make these names in the new county variable of the counties data to be in title format. We can use the str_to_title() function of the stringr package to do this.
Great! Now the county information is the same for the counties and pm data.
We can use the inner_join() function of the dplyr package to join the datasets together based on the county variables in each. This function will keep all rows that are in both datasets.
Rows: 3,926
Columns: 52
$ state.x <chr> "alabama", "alabama", "alabama", "alabama…
$ county <chr> "Baldwin", "Bibb", "Bibb", "Butler", "But…
$ id <fct> 1003.001, 13021.0007, 13021.0012, 39017.0…
$ value <dbl> 9.597647, 12.253134, 12.233673, 13.918079…
$ fips <fct> 1003, 13021, 13021, 39017, 39017, 13059, …
$ lat <dbl> 30.49800, 32.77746, 32.80541, 39.49380, 3…
$ lon <dbl> -87.88141, -83.64110, -83.54352, -84.3543…
$ state.y <chr> "Alabama", "Georgia", "Georgia", "Ohio", …
$ city <chr> "In a city", "In a city", "In a city", "I…
$ CMAQ <dbl> 8.098836, 11.716801, 11.716801, 11.321991…
$ zcta <fct> 36532, 31206, 31020, 45044, 45015, 30605,…
$ zcta_area <dbl> 190980522, 72325015, 276913325, 98746815,…
$ zcta_pop <dbl> 27829, 29072, 2541, 52822, 12038, 39952, …
$ imp_a500 <dbl> 0.01730104, 35.64359862, 0.28200692, 27.4…
$ imp_a1000 <dbl> 1.4096021, 24.4824827, 0.2973616, 28.2887…
$ imp_a5000 <dbl> 3.3360118, 8.7317283, 2.4691097, 22.69740…
$ imp_a10000 <dbl> 1.9879187, 9.1999720, 1.9873487, 11.90155…
$ imp_a15000 <dbl> 1.4386207, 6.4619966, 3.6435089, 8.405292…
$ county_area <dbl> 4117521611, 646879637, 646879637, 1209668…
$ county_pop <dbl> 182265, 155547, 155547, 368130, 368130, 1…
$ log_dist_to_prisec <dbl> 4.648181, 7.635438, 7.576493, 5.959728, 5…
$ log_pri_length_5000 <dbl> 8.517193, 10.215058, 10.659655, 9.747731,…
$ log_pri_length_10000 <dbl> 9.210340, 12.116408, 11.653566, 10.734382…
$ log_pri_length_15000 <dbl> 9.630228, 12.591833, 12.313347, 11.172817…
$ log_pri_length_25000 <dbl> 11.32735, 13.12475, 13.02383, 12.14238, 1…
$ log_prisec_length_500 <dbl> 7.295356, 6.214608, 6.214608, 8.104926, 7…
$ log_prisec_length_1000 <dbl> 8.195119, 7.600902, 7.600902, 9.180109, 8…
$ log_prisec_length_5000 <dbl> 10.81504, 11.61283, 11.34202, 11.63677, 1…
$ log_prisec_length_10000 <dbl> 11.88680, 13.23991, 12.47152, 12.62117, 1…
$ log_prisec_length_15000 <dbl> 12.20572, 13.74532, 13.37704, 13.26170, 1…
$ log_prisec_length_25000 <dbl> 13.41395, 14.28483, 14.25295, 14.16745, 1…
$ log_nei_2008_pm25_sum_10000 <dbl> 0.3180354, 5.5380414, 0.1972941, 7.230784…
$ log_nei_2008_pm25_sum_15000 <dbl> 1.967359, 5.538041, 5.536822, 7.408732, 5…
$ log_nei_2008_pm25_sum_25000 <dbl> 5.067308, 5.986616, 5.986572, 7.538614, 7…
$ log_nei_2008_pm10_sum_10000 <dbl> 1.3558851, 5.6035407, 0.9849611, 7.278576…
$ log_nei_2008_pm10_sum_15000 <dbl> 2.2678341, 5.6035407, 5.5971561, 7.489928…
$ log_nei_2008_pm10_sum_25000 <dbl> 5.6287284, 6.0302900, 6.0347672, 7.633004…
$ popdens_county <dbl> 44.265706, 240.457407, 240.457407, 304.32…
$ popdens_zcta <dbl> 145.716431, 401.963277, 9.176156, 534.923…
$ nohs <dbl> 3.300, 8.700, 6.800, 1.300, 3.500, 3.800,…
$ somehs <dbl> 4.900, 24.700, 17.500, 3.300, 7.700, 6.80…
$ hs <dbl> 25.10, 32.60, 46.60, 33.40, 33.40, 17.80,…
$ somecollege <dbl> 19.7, 12.9, 18.7, 23.0, 23.2, 16.1, 18.8,…
$ associate <dbl> 8.200, 4.800, 5.000, 8.700, 8.100, 5.100,…
$ bachelor <dbl> 25.30, 8.90, 4.00, 22.20, 16.20, 25.40, 5…
$ grad <dbl> 13.50, 7.30, 1.30, 8.10, 7.90, 25.00, 3.1…
$ pov <dbl> 6.100, 38.800, 26.800, 0.900, 6.900, 12.1…
$ hs_orless <dbl> 33.30, 66.00, 70.90, 38.00, 44.60, 28.40,…
$ urc2013 <dbl> 4, 4, 4, 2, 2, 4, 6, 2, 4, 1, 1, 1, 3, 4,…
$ urc2006 <dbl> 5, 4, 4, 2, 2, 4, 6, 2, 4, 1, 1, 1, 3, 4,…
$ aod <dbl> 37.36364, 36.25000, 30.45455, 48.36364, 5…
$ geom <MULTIPOLYGON [°]> MULTIPOLYGON (((-87.93757 3.…
Nice! we can see that we have add a geom variable to the pm data.
Now we can use this to color the counties in our plot based on the value variable of our pm data, which you may recall is the actual monitor data for fine particulate air pollution at each monitor.
WE can do so using the scale_fill_gradientn() function of the ggplot2 package which creates color gradient based on a variable. In this case it is the variable that was specified as the fill in the aes function of the geom_sf() function. We specified that it would be the value variable of the pm data.
This scale_fill_gradientn() function also allows you to specify the colors, what to do about NA values (should they be a specific color or transparent) and the breaks, limits, labels and name/title on the legend for the color gradient.
truth <-ggplot(data = world) +
coord_sf(xlim = c(-125, -66), ylim = c(24.5, 50), expand = FALSE)+
geom_sf(data = map_data, aes(fill = value)) +
scale_fill_gradientn(colours=topo.colors(7), na.value = "transparent",
breaks=c(0,10,20),labels=c(0,10,20),
limits=c(0,23.5), name = "PM ug/m3") +
ggtitle("True PM 2.5 levels") +
theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank(),
axis.title.y=element_blank(),
axis.text.y=element_blank(),
axis.ticks.y=element_blank())
truth
Nice!
Now let’s do the same with our predicted outcome values.
Let’s grab both the testing and training predicted outcome values so that we have as much data as possible.
First we need to fit our training data with our final model to be able to get the predictions for the monitors included in the training set. We did this using the last_fit() function, but the output of this makes it difficult to grab the predicted values for the training data, and it is also difficult to get the id variables for the testing data.
Thus we will use the parsnip fit() and predict() functions to do this outside of the workflows package like so:
Question Opportunity
Why do we not need pre-processed data?
Click here to reveal the answer.
Since we are using a workflow, the data will be pre-processed when it is fit as well.
# A tibble: 584 x 5
.pred value fips county id
<dbl> <dbl> <fct> <chr> <fct>
1 10.0 9.60 1003 Baldwin 1003.001
2 11.0 10.8 1027 Clay 1027.0001
3 11.5 11.2 1033 Colbert 1033.1002
4 12.0 12.4 1055 Etowah 1055.001
5 10.8 10.5 1069 Houston 1069.0003
6 14.5 15.6 1073 Jefferson 1073.0023
7 12.1 12.4 1073 Jefferson 1073.1005
8 11.0 11.1 1073 Jefferson 1073.1009
9 13.9 14.6 1073 Jefferson 1073.2003
10 11.8 12.0 1073 Jefferson 1073.5002
# … with 574 more rows
# A tibble: 292 x 5
.pred value fips county id
<dbl> <dbl> <fct> <chr> <fct>
1 11.7 11.7 1049 DeKalb 1049.1003
2 12.6 13.1 1073 Jefferson 1073.101
3 12.3 12.2 1073 Jefferson 1073.2006
4 12.0 12.2 1089 Madison 1089.0014
5 11.5 11.4 1103 Morgan 1103.0011
6 12.4 12.2 1121 Talladega 1121.0002
7 10.8 10.9 4013 Maricopa 4013.4003
8 10.4 10.6 4021 Pinal 4021.0001
9 12.0 14.1 4023 Santa Cruz 4023.0004
10 7.69 5.83 4025 Yavapai 4025.2002
# … with 282 more rows
Now we can combine this data for the predictions for all monitors using the bind_rows() function of the dplyr package, which will essentially append the second dataset to the first.
# A tibble: 876 x 5
.pred value fips county id
<dbl> <dbl> <fct> <chr> <fct>
1 11.7 11.7 1049 DeKalb 1049.1003
2 12.6 13.1 1073 Jefferson 1073.101
3 12.3 12.2 1073 Jefferson 1073.2006
4 12.0 12.2 1089 Madison 1089.0014
5 11.5 11.4 1103 Morgan 1103.0011
6 12.4 12.2 1121 Talladega 1121.0002
7 10.8 10.9 4013 Maricopa 4013.4003
8 10.4 10.6 4021 Pinal 4021.0001
9 12.0 14.1 4023 Santa Cruz 4023.0004
10 7.69 5.83 4025 Yavapai 4025.2002
# … with 866 more rows
Great! as we can see there are 876 values like we would expect for all of the monitors. We can use the county variable to combine this with the counties data like we did with the pm data previously so that we can use the value variable as a color scheme for our map.
map_data <- inner_join(counties, all_pred, by = "county")
pred <- ggplot(data = world) +
coord_sf(xlim = c(-125, -66), ylim = c(24.5, 50),
expand = FALSE) +
geom_sf(data = map_data, aes(fill = .pred)) +
scale_fill_gradientn(colours=topo.colors(7), na.value = "transparent",
breaks=c(0,10,20),labels=c(0,10,20),
limits=c(0,23.5), name = "PM ug/m3") +
ggtitle("Predicted PM 2.5 levels")+
theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank(),
axis.title.y=element_blank(),
axis.text.y=element_blank(),
axis.ticks.y=element_blank())
pred

Now we will use the patchwork package to combine our last two plots. This allows us to combine plots using the + or the / . The + will place plots side by side and the / will place plots top to bottom.
Now let’s just combine the truth plot and the prediction plots together:

We can see that the predicted fine particle air pollution values in (ug/m3) are quite similar to the true values measured by the actual gravimetric monitors. We can also see that southern California has some large counties with worse pollution (as they are yellow and thus have much higher particulate matter levels).
Let’s add some text to our plot to explain it a bit more.

LS0tCnRpdGxlOiAiT3BlbiBDYXNlIFN0dWRpZXM6IFByZWRpY3RpbmcgQW5udWFsIEFpciBQb2xsdXRpb24gIgpjc3M6IHN0eWxlLmNzcwpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHNlbGZfY29udGFpbmVkOiB5ZXMKICAgIGNvZGVfZG93bmxvYWQ6IHllcwogICAgaGlnaGxpZ2h0OiB0YW5nbwogICAgbnVtYmVyX3NlY3Rpb25zOiBubwogICAgdGhlbWU6IGNvc21vCiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKICBwZGZfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwogIHdvcmRfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwoKLS0tCjxzdHlsZT4KI1RPQyB7CiAgYmFja2dyb3VuZDogdXJsKCJodHRwczovL29wZW5jYXNlc3R1ZGllcy5naXRodWIuaW8vaW1nL2xvZ28uanBnIik7CiAgYmFja2dyb3VuZC1zaXplOiBjb250YWluOwogIHBhZGRpbmctdG9wOiAyNDBweCAhaW1wb3J0YW50OwogIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7Cn0KPC9zdHlsZT4KCjwhLS0gT3BlbiBhbGwgbGlua3MgaW4gbmV3IHRhYi0tPiAgCjxiYXNlIHRhcmdldD0iX2JsYW5rIi8+IAoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoa25pdHIpCmxpYnJhcnkoaGVyZSkKa25pdHI6Om9wdHNfY2h1bmskc2V0KGluY2x1ZGUgPSBUUlVFLCBjb21tZW50ID0gTkEsIGVjaG8gPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIGNhY2hlID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICBmaWcuYWxpZ24gPSAiY2VudGVyIiwgb3V0LndpZHRoID0gJzkwJScpCmBgYAoKCiMjIyMgey5vdXRsaW5lIH0KYGBge3IsIGVjaG8gPSBGQUxTRSwgb3V0LndpZHRoID0gIjgwMCBweCJ9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltZyIsICJtYWluX3Bsb3RfbWFwcy5wbmciKSkKYGBgCgojIyMjCgojIyB7LmRpc2NsYWltZXJfYmxvY2t9CgoqKkRpc2NsYWltZXIqKjogVGhlIHB1cnBvc2Ugb2YgdGhlIFtPcGVuIENhc2UgU3R1ZGllc10oaHR0cHM6Ly9vcGVuY2FzZXN0dWRpZXMuZ2l0aHViLmlvKXt0YXJnZXQ9Il9ibGFuayJ9IHByb2plY3QgaXMgKip0byBkZW1vbnN0cmF0ZSB0aGUgdXNlIG9mIHZhcmlvdXMgZGF0YSBzY2llbmNlIG1ldGhvZHMsIHRvb2xzLCBhbmQgc29mdHdhcmUgaW4gdGhlIGNvbnRleHQgb2YgbWVzc3ksIHJlYWwtd29ybGQgZGF0YSoqLiAKQSBnaXZlbiBjYXNlIHN0dWR5IGRvZXMgbm90IGNvdmVyIGFsbCBhc3BlY3RzIG9mIHRoZSByZXNlYXJjaCBwcm9jZXNzLCBpcyBub3QgY2xhaW1pbmcgdG8gYmUgdGhlIG1vc3QgYXBwcm9wcmlhdGUgd2F5IHRvIGFuYWx5emUgYSBnaXZlbiBkYXRhIHNldCwgYW5kIHNob3VsZCBub3QgYmUgdXNlZCBpbiB0aGUgY29udGV4dCBvZiBtYWtpbmcgcG9saWN5IGRlY2lzaW9ucyB3aXRob3V0IGV4dGVybmFsIGNvbnN1bHRhdGlvbiBmcm9tIHNjaWVudGlmaWMgZXhwZXJ0cy4gCgojIyMjIHsubGljZW5zZV9ibG9ja30KClRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQ3JlYXRpdmUgQ29tbW9ucyBBdHRyaWJ1dGlvbi1Ob25Db21tZXJjaWFsIDMuMCBbKENDIEJZLU5DIDMuMCldKGh0dHBzOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9ieS1uYy8zLjAvdXMvKXt0YXJnZXQ9Il9ibGFuayJ9IFVuaXRlZCBTdGF0ZXMgTGljZW5zZS4KCiMjIyMKCgojICoqTW90aXZhdGlvbioqCioqKgpBIHZhcmlldHkgb2YgZGlmZmVyZW50IHNvdXJjZXMgY29udHJpYnV0ZSBkaWZmZXJlbnQgdHlwZXMgb2YgcG9sbHV0YW50cyB0byB3aGF0IHdlIGNhbGwgYWlyIHBvbGx1dGlvbi4gCgpTb21lIHNvdXJjZXMgYXJlIG5hdHVyYWwgd2hpbGUgb3RoZXJzIGFyZSBhbnRocm9wb2dlbmljIChodW1hbiBkZXJpdmVkKToKCjxwIGFsaWduPSJjZW50ZXIiPgo8aW1nIHdpZHRoPSI2MDAiIHNyYz0iaHR0cHM6Ly93d3cubnBzLmdvdi9zdWJqZWN0cy9haXIvaW1hZ2VzL1NvdXJjZXNfR3JhcGhpY19IdWdlLmpwZz9tYXh3aWR0aD0xMjAwJm1heGhlaWdodD0xMjAwJmF1dG9yb3RhdGU9ZmFsc2UiPgo8L3A+CgojIyMjIyBbW3NvdXJjZV1dKGh0dHBzOi8vd3d3Lmdvb2dsZS5jb20vdXJsP3NhPWkmdXJsPWh0dHBzJTNBJTJGJTJGd3d3Lm5wcy5nb3YlMkZzdWJqZWN0cyUyRmFpciUyRnNvdXJjZXMuaHRtJnBzaWc9QU92VmF3MnY3QVZ4U0Y4WlNBUEVoTnVkVnRiTiZ1c3Q9MTU4NTc3MDk2NjIxNzAwMCZzb3VyY2U9aW1hZ2VzJmNkPXZmZSZ2ZWQ9MENBSVFqUnhxRndvVENQRE42NnFfeGVnQ0ZRQUFBQUFkQUFBQUFCQUQpe3RhcmdldD0iX2JsYW5rIn0KCiMjIyBNYWpvciB0eXBlcyBvZiBhaXIgcG9sbHV0YW50cwoKMSkgKipHYXNlb3VzKiogLSBDYXJib24gTW9ub3hpZGUgKENPKSwgT3pvbmUgKE9+M34pLCBOaXRyb2dlbiBPeGlkZXMoTk8sIE5PfjJ+KSwgU3VscGhlciBEaW94aWRlIChTT34yfikKMikgKipQYXJ0aWN1bGF0ZSoqIC0gc21hbGwgbGlxdWlkcyBhbmQgc29saWRzIHN1c3BlbmRlZCBpbiB0aGUgYWlyIChpbmNsdWRlcyBsZWFkLSBjYW4gaW5jbHVkZSBjZXJ0YWluIHR5cGVzIG9mIGR1c3QpCjMpICoqRHVzdCoqIC0gc21hbGwgc29saWRzIChsYXJnZXIgdGhhbiBwYXJ0aWN1bGF0ZXMpIHRoYXQgY2FuIGJlIHN1c3BlbmRlZCBpbiB0aGUgYWlyIGZvciBzb21lIHRpbWUgYnV0IGV2ZW50dWFsbHkgc2V0dGxlCjQpICoqQmlvbG9naWNhbCoqIC0gcG9sbGVuLCBiYWN0ZXJpYSwgdmlydXNlcywgbW9sZCBzcG9yZXMKClNlZSBbaGVyZV0oaHR0cDovL3d3dy5yZWRsb2dlbnYuY29tL3dvcmtlci1zYWZldHkvcGFydC0xLWR1c3QtYW5kLXBhcnRpY3VsYXRlLW1hdHRlcikgZm9yIG1vcmUgZGV0YWlsIG9uIHRoZSB0eXBlcyBvZiBwb2xsdXRhbnRzIGluIHRoZSBhaXIuCgoKIyMjIFBhcnRpY3VsYXRlIHBvbGx1dGlvbiAKCkFpciBwb2xsdXRpb24gcGFydGljdWxhdGVzIGFyZSBnZW5lcmFsbHkgZGVzY3JpYmVkIGJ5IHRoZWlyICoqc2l6ZSoqLgoKVGhlcmUgYXJlIDMgbWFqb3IgY2F0ZWdvcmllczoKCjEpICoqTGFyZ2UgQ29hcnNlKiogUGFydGljdWxhdGUgTWF0ZXIgLSBoYXMgZGlhbWV0ZXIgb2YgPjEwIG1pY3JvbWV0ZXJzICgxMCDCtW0pIAoKMikgKipDb2Fyc2UqKiBQYXJ0aWN1bGF0ZSBNYXRlciAoY2FsbGVkICoqUE1+MTAtMi41fioqKSAtIGhhcyBkaWFtZXRlciBvZiBiZXR3ZWVuIDIuNSDCtW0gYW5kIDEwIMK1bQoKMykgKipGaW5lKiogUGFydGljdWxhdGUgTWF0ZXIgKGNhbGxlZCAqKlBNfjIuNX4qKikgLSBoYXMgZGlhbWV0ZXIgb2YgPCAyLjUgwrVtIAoKKipQTX4xMH4qKiBpbmNsdWRlcyBhbnkgcGFydGljdWxhdGUgbWF0ZXIgPDEwIMK1bSAoYm90aCBjb2Fyc2UgYW5kIGZpbmUgcGFydGljdWxhdGUgbWF0ZXIpCgpIZXJlIHlvdSBjYW4gc2VlIGhvdyB0aGVzZSBzaXplcyBjb21wYXJlIHdpdGggYSBodW1hbiBoYWlyOgoKYGBge3IsIGVjaG8gPSBGQUxTRSwgb3V0LndpZHRoPSAiNjAwIHB4In0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1nIiwgInBtMi41X3NjYWxlX2dyYXBoaWMtY29sb3JfMi5qcGciKSkKYGBgCgojIyMjIyBbW3NvdXJjZV1dKGh0dHBzOi8vd3d3LmVwYS5nb3YvcG0tcG9sbHV0aW9uL3BhcnRpY3VsYXRlLW1hdHRlci1wbS1iYXNpY3Mpe3RhcmdldD0iX2JsYW5rIn0KCjwhLS0gPHAgYWxpZ249ImNlbnRlciI+IC0tPgo8IS0tICAgPGltZyB3aWR0aD0iNTAwIiBzcmM9Imh0dHBzOi8vd3d3LnNlbnNpcmlvbi5jb20vaW1hZ2VzL3NlbnNpcmlvbi1zcGVjaWFsaXN0LWFydGljbGUtZmlndXJlLTEtY2RkNzAuanBnIj4gLS0+CjwhLS0gPC9wPiAtLT4KCgo8dT5UaGUgZm9sbG93aW5nIHBsb3QgYW5kIHRhYmxlIHNob3cgdGhlIHJlbGF0aXZlIHNpemVzIG9mIHRoZXNlIGRpZmZlcmVudCBwb2xsdXRhbnRzIGluIG1pY3JvbWV0ZXJzICjCtW0pOjwvdT4KCjxwIGFsaWduPSJjZW50ZXIiPgogIDxpbWcgd2lkdGg9IjYwMCIgc3JjPSJodHRwczovL3VwbG9hZC53aWtpbWVkaWEub3JnL3dpa2lwZWRpYS9jb21tb25zL3RodW1iL2QvZGYvQWlyYm9ybmUtcGFydGljdWxhdGUtc2l6ZS1jaGFydC5zdmcvODAwcHgtQWlyYm9ybmUtcGFydGljdWxhdGUtc2l6ZS1jaGFydC5zdmcucG5nIj4KPC9wPgoKIyMjIyMgW1tzb3VyY2VdXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9QYXJ0aWN1bGF0ZXMpe3RhcmdldD0iX2JsYW5rIn0KCgo8cCBhbGlnbj0iY2VudGVyIj4KICA8aW1nIHdpZHRoPSI1MDAiIHNyYz0iaHR0cHM6Ly93d3cuZnJvbnRpZXJzaW4ub3JnL2ZpbGVzL0FydGljbGVzLzUwNTU3MC9mcHViaC0wOC0wMDAxNC1IVE1ML2ltYWdlX20vZnB1YmgtMDgtMDAwMTQtdDAwMi5qcGciPgo8L3A+CgojIyMjIyBbW3NvdXJjZV1dKGh0dHBzOi8vd3d3LmZyb250aWVyc2luLm9yZy9hcnRpY2xlcy8xMC4zMzg5L2ZwdWJoLjIwMjAuMDAwMTQvZnVsbCl7dGFyZ2V0PSJfYmxhbmsifQoKCjx1PlRoaXMgdGFibGUgc2hvd3MgaG93IGRlZXBseSBzb21lIG9mIHRoZSBzbWFsbGVyIGZpbmUgcGFydGljbGVzIGNhbiBwZW5ldHJhdGUgd2l0aGluIHRoZSBodW1hbiBib2R5OjwvdT4KCjxwIGFsaWduPSJjZW50ZXIiPgogIDxpbWcgd2lkdGg9IjUwMCIgc3JjPSJodHRwczovL3d3dy5mcm9udGllcnNpbi5vcmcvZmlsZXMvQXJ0aWNsZXMvNTA1NTcwL2ZwdWJoLTA4LTAwMDE0LUhUTUwvaW1hZ2VfbS9mcHViaC0wOC0wMDAxNC10MDAxLmpwZyI+CjwvcD4KCiMjIyMjIFtbc291cmNlXV0oaHR0cHM6Ly93d3cuZnJvbnRpZXJzaW4ub3JnL2FydGljbGVzLzEwLjMzODkvZnB1YmguMjAyMC4wMDAxNC9mdWxsKXt0YXJnZXQ9Il9ibGFuayJ9CgoKIyMjIE5lZ2F0aXZlIGltcGFjdCBvZiBwYXJ0aWN1bGF0ZSBleHBvc3VyZSBvbiBoZWFsdGggCgpFeHBvc3VyZSB0byBhaXIgcG9sbHV0aW9uIGlzIGFzc29jaWF0ZWQgd2l0aCBoaWdoZXIgcmF0ZXMgb2YgW21vcnRhbGl0eV0oaHR0cHM6Ly93d3cubmNiaS5ubG0ubmloLmdvdi9wbWMvYXJ0aWNsZXMvUE1DNTc4MzE4Ni8pe3RhcmdldD0iX2JsYW5rIn0gaW4gb2xkZXIgYWR1bHRzIGFuZCBpcyBrbm93biB0byBiZSBhIHJpc2sgZmFjdG9yIGZvciBtYW55IGRpc2Vhc2VzIGFuZCBjb25kaXRpb25zIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG86CgoxKSBbQXN0aG1hXShodHRwczovL3d3dy5uY2JpLm5sbS5uaWguZ292L3B1Ym1lZC8yOTI0MzkzNyl7dGFyZ2V0PSJfYmxhbmsifSAtIGZpbmUgcGFydGljbGUgZXhwb3N1cmUgKCoqUE1+Mi41fioqKSB3YXMgZm91bmQgdG8gYmUgYXNzb2NpYXRlZCB3aXRoIGhpZ2hlciByYXRlcyBvZiBhc3RobWEgaW4gY2hpbGRyZW4KMikgW0luZmxhbW1hdGlvbiBpbiB0eXBlIDEgZGlhYmV0ZXNdKGh0dHBzOi8vd3d3Lm5jYmkubmxtLm5paC5nb3YvcHVibWVkLzMxNDE5NzY1KXt0YXJnZXQ9Il9ibGFuayJ9IC0gZmluZSBwYXJ0aWNsZSBleHBvc3VyZSAoKipQTX4yLjV+KiopIGZyb20gdHJhZmZpYy1yZWxhdGVkIGFpciBwb2xsdXRpb24gd2FzIGFzc29jaWF0ZWQgd2l0aCBpbmNyZWFzZWQgbWVhc3VyZXMgb2YgaW5mbGFtbWF0b3J5IG1hcmtlcnMgaW4geW91dGhzIHdpdGggVHlwZSAxIGRpYWJldGVzCjMpIFtMdW5nIGZ1bmN0aW9uIGFuZCBlbXBoeXNlbWFdKGh0dHBzOi8vd3d3Lm5jYmkubmxtLm5paC5nb3YvcHVibWVkLzMxNDA4MTM1KXt0YXJnZXQ9Il9ibGFuayJ9IC0gaGlnaGVyIGNvbmNlbnRyYXRpb25zIG9mIG96b25lIChPfjN+KSwgbml0cm9nZW4gb3hpZGVzIChOT354fiksIGJsYWNrIGNhcmJvbiwgYW5kIGZpbmUgcGFydGljbGUgZXhwb3N1cmUgKipQTX4yLjV+KiogLCBhdCBzdHVkeSBiYXNlbGluZSB3ZXJlIHNpZ25pZmljYW50bHkgYXNzb2NpYXRlZCB3aXRoIGdyZWF0ZXIgaW5jcmVhc2VzIGluIHBlcmNlbnQgZW1waHlzZW1hIHBlciAxMCB5ZWFycyAKNCkgW0xvdyBiaXJ0aHdlaWdodF0oaHR0cHM6Ly93d3cubmNiaS5ubG0ubmloLmdvdi9wdWJtZWQvMzEzODY2NDMpe3RhcmdldD0iX2JsYW5rIn0gLSBmaW5lIHBhcnRpY2xlIGV4cG9zdXJlKCoqUE1+Mi41fioqKSB3YXMgYXNzb2NpYXRlZCB3aXRoIGxvd2VyIGJpcnRoIHdlaWdodCBpbiBmdWxsLXRlcm0gbGl2ZSBiaXJ0aHMKNSkgW1ZpcmFsIEluZmVjdGlvbl0oaHR0cHM6Ly93d3cudGFuZGZvbmxpbmUuY29tL2RvaS9mdWxsLzEwLjEwODAvMDg5NTgzNzA3MDE2NjU0MzQpe3RhcmdldD0iX2JsYW5rIn0gLSBoaWdoZXIgcmF0ZXMgb2YgaW5mZWN0aW9uIGFuZCBpbmNyZWFzZWQgc2V2ZXJpdHkgb2YgaW5mZWN0aW9uIGFyZSBhc3NvY2lhdGVkIHdpdGggaGlnaGVyIGV4cG9zdXJlcyB0byBwb2xsdXRpb24gbGV2ZWxzIGluY2x1ZGluZyBmaW5lIHBhcnRpY2xlIGV4cG9zdXJlICgqKlBNfjIuNX4qKikKClNlZSB0aGlzIFtyZXZpZXcgYXJ0aWNsZV0oaHR0cHM6Ly93d3cuZnJvbnRpZXJzaW4ub3JnL2FydGljbGVzLzEwLjMzODkvZnB1YmguMjAyMC4wMDAxNC9mdWxsKXt0YXJnZXQ9Il9ibGFuayJ9IGZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHNvdXJjZXMgb2YgYWlyIHBvbGx1dGlvbiBhbmQgdGhlIGluZmx1ZW5jZSBvZiBhaXIgcG9sbHV0aW9uIG9uIGhlYWx0aC4KCiMjIyBTcGFyc2UgbW9uaXRvcmluZyBpcyBwcm9ibGVtYXRpYyBmb3IgUHVibGljIEhlYWx0aAoKSGlzdG9yaWNhbGx5LCBlcGlkZW1pb2xvZ2ljYWwgc3R1ZGllcyB3b3VsZCBhc3Nlc3MgdGhlIGluZmx1ZW5jZSBvZiBhaXIgcG9sbHV0aW9uIG9uIGhlYWx0aCBvdXRjb21lcyBieSByZWx5aW5nIG9uIGEgbnVtYmVyIG9mIG1vbml0b3JzIGxvY2F0ZWQgYXJvdW5kIHRoZSBjb3VudHJ5LiAKSG93ZXZlciwgYXMgY2FuIGJlIHNlZW4gaW4gdGhlIGZvbGxvd2luZyBmaWd1cmUsIHRoZXNlIG1vbml0b3JzIGFyZSByZWxhdGl2ZWx5IHNwYXJzZSBpbiBjZXJ0YWluIHJlZ2lvbnMgb2YgdGhlIGNvdW50cnkuIApGdXJ0aGVybW9yZSwgZHJhbWF0aWMgZGlmZmVyZW5jZXMgaW4gcG9sbHV0aW9uIHJhdGVzIGNhbiBiZSBzZWVuIGV2ZW4gd2l0aGluIHRoZSBzYW1lIGNpdHkuCgo8cCBhbGlnbj0iY2VudGVyIj4KICA8aW1nIHdpZHRoPSI0MDAiIHNyYz0iaHR0cHM6Ly93d3cubmNiaS5ubG0ubmloLmdvdi9wbWMvYXJ0aWNsZXMvUE1DNDEzNzI3Mi9iaW4vMTQ3Ni0wNjlYLTEzLTYzLTEuanBnIj4KPC9wPgoKIyMjIyMgW1tzb3VyY2VdXShodHRwczovL2Voam91cm5hbC5iaW9tZWRjZW50cmFsLmNvbS9hcnRpY2xlcy8xMC4xMTg2LzE0NzYtMDY5WC0xMy02Myl7dGFyZ2V0PSJfYmxhbmsifQoKVGhpcyBsYWNrIG9mIGdyYW51bGFyaXR5IGluIGFpciBwb2xsdXRpb24gbW9uaXRvcmluZyBoYXMgaGluZGVyZWQgb3VyIGFiaWxpdHkgdG8gZGlzY2VybiB0aGUgZnVsbCBpbXBhY3Qgb2YgYWlyIHBvbGx1dGlvbiBvbiBoZWFsdGggYW5kIHRvIGlkZW50aWZ5IGF0LXJpc2sgbG9jYXRpb25zLiAKCgojIyMgTWFjaGluZSBsZWFybmluZyBvZmZlcnMgYSBzb2x1dGlvbgoKQW4gW2FydGljbGVdKGh0dHBzOi8vZWhqb3VybmFsLmJpb21lZGNlbnRyYWwuY29tL2FydGljbGVzLzEwLjExODYvMTQ3Ni0wNjlYLTEzLTYzKXt0YXJnZXQ9Il9ibGFuayJ9IHB1Ymxpc2hlZCBpbiB0aGUgKkVudmlyb25tZW50YWwgSGVhbHRoKiBqb3VybmFsIGRlYWx0IHdpdGggdGhpcyBpc3N1ZSBieSB1c2luZyBkYXRhLCBpbmNsdWRpbmcgcG9wdWxhdGlvbiBkZW5zaXR5LCByb2FkIGRlbnNpdHksIGFtb25nIG90aGVyIGZlYXR1cmVzLCB0byBtb2RlbCBvciBwcmVkaWN0IGFpciBwb2xsdXRpb24gbGV2ZWxzIGF0IGEgbW9yZSBsb2NhbGl6ZWQgc2NhbGUgdXNpbmcgbWFjaGluZSBsZWFybmluZyAoTUwpIG1ldGhvZHMuIAoKYGBge3IsIGVjaG8gPSBGQUxTRSwgb3V0LndpZHRoPSAiODAwIHB4In0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1nIiwgInRoZXBhcGVyLnBuZyIpKQpgYGAKCiMjIyMgey5yZWZlcmVuY2VfYmxvY2t9Cllhbm9za3ksIEouIEQuIGV0IGFsLiBTcGF0aW8tdGVtcG9yYWwgbW9kZWxpbmcgb2YgcGFydGljdWxhdGUgYWlyIHBvbGx1dGlvbiBpbiB0aGUgY29udGVybWlub3VzIFVuaXRlZCBTdGF0ZXMgdXNpbmcgZ2VvZ3JhcGhpYyBhbmQgbWV0ZW9yb2xvZ2ljYWwgcHJlZGljdG9ycy4gKkVudmlyb24gSGVhbHRoKiAxMywgNjMgKDIwMTQpLgoKIyMjIwoKVGhlIGF1dGhvcnMgb2YgdGhpcyBhcnRpY2xlIHN0YXRlIHRoYXQ6Cgo+ICJFeHBvc3VyZSB0byBhdG1vc3BoZXJpYyBwYXJ0aWN1bGF0ZSBtYXR0ZXIgKFBNKSByZW1haW5zIGFuIGltcG9ydGFudCBwdWJsaWMgaGVhbHRoIGNvbmNlcm4sIGFsdGhvdWdoIGl0IHJlbWFpbnMgZGlmZmljdWx0IHRvIHF1YW50aWZ5IGFjY3VyYXRlbHkgYWNyb3NzIGxhcmdlIGdlb2dyYXBoaWMgYXJlYXMgd2l0aCBzdWZmaWNpZW50bHkgaGlnaCBzcGF0aWFsIHJlc29sdXRpb24uIFJlY2VudCBlcGlkZW1pb2xvZ2ljIGFuYWx5c2VzIGhhdmUgZGVtb25zdHJhdGVkIHRoZSBpbXBvcnRhbmNlIG9mIHNwYXRpYWxseS0gYW5kIHRlbXBvcmFsbHktcmVzb2x2ZWQgZXhwb3N1cmUgZXN0aW1hdGVzLCB3aGljaCBzaG93IGxhcmdlciBQTS1tZWRpYXRlZCBoZWFsdGggZWZmZWN0cyBhcyBjb21wYXJlZCB0byBuZWFyZXN0IG1vbml0b3Igb3IgY291bnR5LXNwZWNpZmljIGFtYmllbnQgY29uY2VudHJhdGlvbnMuIiAKCgpgYGB7ciwgZWNobyA9IEZBTFNFLCBvdXQud2lkdGg9ICI3MDAgcHgiLCBldmFsID0gRkFMU0V9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltZyIsICJkZWF0aHMucG5nIikpCmBgYAoKVGhlIGFydGljbGUgYWJvdmUgZGVtb25zdHJhdGVzIHRoYXQgbWFjaGluZSBsZWFybmluZyBtZXRob2RzIGNhbiBiZSB1c2VkIHRvIHByZWRpY3QgYWlyIHBvbGx1dGlvbiBsZXZlbHMgd2hlbiB0cmFkaXRpb25hbCBtb25pdG9yaW5nIHN5c3RlbXMgYXJlIG5vdCBhdmFpbGFibGUgaW4gYSBwYXJ0aWN1bGFyIGFyZWEgb3Igd2hlbiB0aGVyZSBpcyBub3QgZW5vdWdoIHNwYXRpYWwgZ3JhbnVsYXJpdHkgd2l0aCBjdXJyZW50IG1vbml0b3Jpbmcgc3lzdGVtcy4gCldlIHdpbGwgdXNlIHNpbWlsYXIgbWV0aG9kcyB0byBwcmVkaWN0IGFubnVhbCBhaXIgcG9sbHV0aW9uIGxldmVscyBzcGF0aWFsbHkgd2l0aGluIHRoZSBVUy4KCgojIyBNYWluIFF1ZXN0aW9uCioqKgoKIyMjIyB7Lm1haW5fcXVlc3Rpb25fYmxvY2t9CjxiPjx1PiBPdXIgbWFpbiBxdWVzdGlvbjogPC91PjwvYj4KCjEpIENhbiB3ZSBwcmVkaWN0IGFubnVhbCBhdmVyYWdlIGFpciBwb2xsdXRpb24gY29uY2VudHJhdGlvbnMgYXQgdGhlIGdyYW51bGFyaXR5IG9mIHppcCBjb2RlIHJlZ2lvbmFsIGxldmVscyB1c2luZyBwcmVkaWN0b3JzIHN1Y2ggYXMgZGF0YSBhYm91dCBwb3B1bGF0aW9uIGRlbnNpdHksIHVyYmFuaXphdGlvbiwgcm9hZCBkZW5zaXR5LCBhcyB3ZWxsIGFzLCBzYXRlbGxpdGUgcG9sbHV0aW9uIGRhdGEgYW5kIGNoZW1pY2FsIG1vZGVsaW5nIGRhdGE/CgojIyMjCgojIyBMZWFybmluZyBPYmplY3RpdmVzCioqKgoKSW4gdGhpcyBjYXNlIHN0dWR5LCB3ZSB3aWxsIHdhbGsgeW91IHRocm91Z2ggaW1wb3J0aW5nIGRhdGEgZnJvbSBDU1YgZmlsZXMgYW5kIHBlcmZvcm1pbmcgbWFjaGluZSBsZWFybmluZyBtZXRob2RzIHRvIHByZWRpY3Qgb3VyIG91dGNvbWUgdmFyaWFibGUgb2YgaW50ZXJlc3QgKGluIHRoaXMgY2FzZSBhbm51YWwgZmluZSBwYXJ0aWNsZSBhaXIgcG9sbHV0aW9uIGVzdGltYXRlcykuIAoKV2Ugd2lsbCBlc3BlY2lhbGx5IGZvY3VzIG9uIHVzaW5nIHBhY2thZ2VzIGFuZCBmdW5jdGlvbnMgZnJvbSB0aGUgW2B0aWR5dmVyc2VgXShodHRwczovL3d3dy50aWR5dmVyc2Uub3JnLyl7dGFyZ2V0PSJfYmxhbmsifSwgYW5kIG1vcmUgc3BlY2lmaWNhbGx5IHRoZSBbYHRpZHltb2RlbHNgXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvdGlkeW1vZGVscy90aWR5bW9kZWxzLnBkZil7dGFyZ2V0PSJfYmxhbmsifSBwYWNrYWdlL2Vjb3N5c3RlbSBwcmltYXJpbHkgZGV2ZWxvcGVkIGFuZCBtYWludGFpbmVkIGJ5IFtNYXggS3Vobl0oaHR0cHM6Ly9yZXNvdXJjZXMucnN0dWRpby5jb20vYXV0aG9ycy9tYXgta3Vobil7dGFyZ2V0PSJfYmxhbmsifSBhbmQgW0RhdmlzIFZhdWdoYW5dKGh0dHBzOi8vcmVzb3VyY2VzLnJzdHVkaW8uY29tL2F1dGhvcnMvZGF2aXMtdmF1Z2hhbil7dGFyZ2V0PSJfYmxhbmsifS4gClRoaXMgcGFja2FnZSBsb2FkcyBtb3JlIG1vZGVsaW5nIHJlbGF0ZWQgcGFja2FnZXMgbGlrZSBgcnNhbXBsZWAsIGByZWNpcGVzYCwgYHBhcnNuaXBgLCBgeWFyZHN0aWNrYCwgYHdvcmtmbG93c2AsIGFuZCBgdHVuZWAgcGFja2FnZXMuIAoKVGhlIHRpZHl2ZXJzZSBpcyBhIGxpYnJhcnkgb2YgcGFja2FnZXMgY3JlYXRlZCBieSBSU3R1ZGlvLiAKV2hpbGUgc29tZSBzdHVkZW50cyBtYXkgYmUgZmFtaWxpYXIgd2l0aCBwcmV2aW91cyBSIHByb2dyYW1taW5nIHBhY2thZ2VzLCB0aGVzZSBwYWNrYWdlcyBtYWtlIGRhdGEgc2NpZW5jZSBpbiBSIGVzcGVjaWFsbHkgZWZmaWNpZW50LgoKCmBgYHtyLCBvdXQud2lkdGggPSAiMjAlIiwgZWNobyA9IEZBTFNFLCBmaWcuYWxpZ24gPSJjZW50ZXIifQppbmNsdWRlX2dyYXBoaWNzKCJodHRwczovL3RpZHl2ZXJzZS50aWR5dmVyc2Uub3JnL2xvZ28ucG5nIikKYGBgCgpUaGUgc2tpbGxzLCBtZXRob2RzLCBhbmQgY29uY2VwdHMgdGhhdCBzdHVkZW50cyB3aWxsIGJlIGZhbWlsaWFyIHdpdGggYnkgdGhlIGVuZCBvZiB0aGlzIGNhc2Ugc3R1ZHkgYXJlOgoKCkRhdGEgc2NpZW5jZSBza2lsbHM6ICAKICAKMS4gRmFtaWxpYXJpdHkgd2l0aCB0aGUgdGlkeW1vZGVscyBlY29zeXN0ZW0KMi4gQWJpbGl0eSB0byBldmFsdWF0ZSBjb3JyZWxhdGlvbiBhbW9uZyBwcmVkaWN0b3IgdmFyaWFibGVzIChgY29ycnBsb3RgIGFuZCBgR0dhbGx5YCkKMy4gQWJpbGl0eSB0byBpbXBsZW1lbnQgdGlkeW1vZGVscyBwYWNrYWdlcyBzdWNoIGFzIGByc2FtcGxlYCB0byBzcGxpdCB0aGUgZGF0YSBpbnRvIHRyYWluaW5nIGFuZCB0ZXN0aW5nIHNldHMgYXMgd2VsbCBhcyBjcm9zcyB2YWxpZGF0aW9uIHNldHMuCjQuIEFiaWxpdHkgdG8gdXNlIHRoZSBgcmVjaXBlc2AsIGBwYXJzbmlwYCwgYW5kIGB3b3JrZmxvd3NgIHRvIHRyYWluIGFuZCB0ZXN0IGEgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwgYW5kIHJhbmRvbSBmb3Jlc3QgbW9kZWwKNS4gRGVtb25zdHJhdGUgaG93IHRvIHZpc3VhbGl6ZSBnZW8tc3BhdGlhbCBkYXRhIHVzaW5nIGBnZ3Bsb3QyYAoKU3RhdGlzdGljYWwgY29uY2VwdHMgYW5kIG1ldGhvZHM6ICAKICAKMS4gQmFzaWMgdW5kZXJzdGFuZGluZyB0aGUgdXRpbGl0eSBvZiBtYWNoaW5lIGxlYXJuaW5nIGZvciBwcmVkaWN0aW9uIGFuZCBjbGFzc2lmaWNhdGlvbgoyLiBVbmRlcnN0YW5kaW5nIG9mIHRoZSBuZWVkIGZvciB0cmFpbmluZyBhbmQgdGVzdCBzZXQKMy4gVW5kZXJzdGFuZGluZyBvZiB0aGUgdXRpbGl0eSBvZiBjcm9zcyB2YWxpZGF0aW9uCjQuIFVuZGVyc3RhbmRpbmcgb2YgcmFuZG9tIGZvcmVzdAo1LiBIb3cgdG8gaW50ZXJwcmV0IHJvb3QgbWVhbiBzcXVhcmVkIGVycm9yIChybXNlKSB0byBhc3Nlc3MgcGVyZm9ybWFuY2UgZm9yIHByZWRpY3Rpb24KCgoKYGBge3IsIG91dC53aWR0aCA9ICIxMDBweCIsIGVjaG8gPSBGQUxTRSwgZmlnLmFsaWduID0iY2VudGVyIn0KaW5jbHVkZV9ncmFwaGljcygiaHR0cHM6Ly9wYnMudHdpbWcuY29tL21lZGlhL0RrQkZwU3NXNEFJeXlJTi5wbmciKQpgYGAKCgpXZSB3aWxsIGJlZ2luIGJ5IGxvYWRpbmcgdGhlIHBhY2thZ2VzIHRoYXQgd2Ugd2lsbCBuZWVkOgoKYGBge3J9CmxpYnJhcnkoaGVyZSkKbGlicmFyeShyZWFkcikKbGlicmFyeShkcGx5cikKbGlicmFyeShza2ltcikKbGlicmFyeShzdW1tYXJ5dG9vbHMpCmxpYnJhcnkobWFncml0dHIpCmxpYnJhcnkoY29ycnBsb3QpCmxpYnJhcnkoUkNvbG9yQnJld2VyKQpsaWJyYXJ5KEdHYWxseSkKbGlicmFyeSh0aWR5bW9kZWxzKQpsaWJyYXJ5KHdvcmtmbG93cykKbGlicmFyeSh2aXApCmxpYnJhcnkodHVuZSkKbGlicmFyeShyYW5kb21Gb3Jlc3QpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShzdHJpbmdyKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KGx3Z2VvbSkKbGlicmFyeShzZikKbGlicmFyeShtYXBzKQpsaWJyYXJ5KHJuYXR1cmFsZWFydGgpCmxpYnJhcnkocmdlb3MpCmxpYnJhcnkocGF0Y2h3b3JrKQpgYGAKCgogUGFja2FnZSAgIHwgVXNlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAotLS0tLS0tLS0tIHwtLS0tLS0tLS0tLS0tCltoZXJlXShodHRwczovL2dpdGh1Yi5jb20vamVubnliYy9oZXJlX2hlcmUpe3RhcmdldD0iX2JsYW5rIn0gICAgICAgfCB0byBlYXNpbHkgbG9hZCBhbmQgc2F2ZSBkYXRhCltyZWFkcl0oaHR0cHM6Ly9yZWFkci50aWR5dmVyc2Uub3JnLyl7dGFyZ2V0PSJfYmxhbmsifSAgICAgIHwgdG8gaW1wb3J0IENTViBmaWxlcwpbZHBseXJdKGh0dHBzOi8vZHBseXIudGlkeXZlcnNlLm9yZy8pe3RhcmdldD0iX2JsYW5rIn0gICAgICB8IHRvIHZpZXcvYXJyYW5nZS9maWx0ZXIvc2VsZWN0L2NvbXBhcmUgc3BlY2lmaWMgc3Vic2V0cyBvZiBkYXRhIApbc2tpbXJdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9za2ltci9pbmRleC5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9ICAgICAgfCB0byBnZXQgYW4gb3ZlcnZpZXcgb2YgZGF0YQpbc3VtbWFyeXRvb2xzXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvc2tpbXIvaW5kZXguaHRtbCl7dGFyZ2V0PSJfYmxhbmsifSAgICAgIHwgdG8gZ2V0IGFuIG92ZXJ2aWV3IG9mIGRhdGEgaW4gYSBkaWZmZXJlbnQgc3R5bGUKW21hZ3JpdHRyXShodHRwczovL21hZ3JpdHRyLnRpZHl2ZXJzZS5vcmcvYXJ0aWNsZXMvbWFncml0dHIuaHRtbCl7dGFyZ2V0PSJfYmxhbmsifSAgIHwgdG8gdXNlIHRoZSBgJTw+JWAgcGlwcGluZyBvcGVyYXRvciAKW2NvcnJwbG90XShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvY29ycnBsb3QvdmlnbmV0dGVzL2NvcnJwbG90LWludHJvLmh0bWwpe3RhcmdldD0iX2JsYW5rIn0gfCB0byBtYWtlIGxhcmdlIGNvcnJlbGF0aW9uIHBsb3RzCltHR2FsbHldKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9HR2FsbHkvR0dhbGx5LnBkZil7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIG1ha2Ugc21hbGxlciBjb3JyZWxhdGlvbiBwbG90cyAgClt0aWR5bW9kZWxzXShodHRwczovL3d3dy50aWR5bW9kZWxzLm9yZyl7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIGxvYWQgaW4gYSBzZXQgb2YgcGFja2FnZXMgKGJyb29tLCBkaWFscywgaW5mZXIsIHBhcnNuaXAsIHB1cnJyLCByZWNpcGVzLCByc2FtcGxlLCB0aWJibGUsIHlhcmRzdGljaykKW3JzYW1wbGVdKGh0dHBzOi8vdGlkeW1vZGVscy5naXRodWIuaW8vcnNhbXBsZS9hcnRpY2xlcy9CYXNpY3MuaHRtbCl7dGFyZ2V0PSJfYmxhbmsifSAgIHwgdG8gc3BsaXQgdGhlIGRhdGEgaW50byB0ZXN0aW5nIGFuZCB0cmFpbmluZyBzZXRzOyB0byBzcGxpdCB0aGUgdHJhaW5pbmcgc2V0IGZvciBjcm9zcy12YWxpZGF0aW9uICAKW3JlY2lwZXNdKGh0dHBzOi8vdGlkeW1vZGVscy5naXRodWIuaW8vcmVjaXBlcy8pe3RhcmdldD0iX2JsYW5rIn0gICB8IHRvIHByZS1wcm9jZXNzIGRhdGEgZm9yIG1vZGVsaW5nIGluIGEgdGlkeSBhbmQgcmVwcm9kdWNpYmxlIHdheSBhbmQgdG8gZXh0cmFjdCBwcmUtcHJvY2Vzc2VkIGRhdGEgKG1ham9yIGZ1bmN0aW9ucyBhcmUgYHJlY2lwZSgpYCAsIGBwcmVwKClgIGFuZCB2YXJpb3VzIHRyYW5zZm9ybWF0aW9uIGBzdGVwXyooKWAgZnVuY3Rpb25zLCBhcyB3ZWxsIGFzIGBqdWljZSgpYCAtIGV4dHJhY3RzIGZpbmFsIHByZS1wcm9jZXNzZWQgdHJhaW5pbmcgZGF0YSBhbmQgYGJha2UoKWAgLSBhcHBsaWVzIHJlY2lwZSBzdGVwcyB0byB0ZXN0aW5nIGRhdGEpLiBTZWUgW2hlcmVdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9yZWNpcGVzL3JlY2lwZXMucGRmKXt0YXJnZXQ9Il9ibGFuayJ9ICBmb3IgbW9yZSBpbmZvLgpbcGFyc25pcF0oaHR0cHM6Ly90aWR5bW9kZWxzLmdpdGh1Yi5pby9wYXJzbmlwLyl7dGFyZ2V0PSJfYmxhbmsifSAgIHwgYW4gaW50ZXJmYWNlIHRvIGNyZWF0ZSBtb2RlbHMgKG1ham9yIGZ1bmN0aW9ucyBhcmUgYGZpdCgpYCwgYHNldF9lbmdpbmUoKWApClt5YXJkc3RpY2tdKGh0dHBzOi8vdGlkeW1vZGVscy5naXRodWIuaW8veWFyZHN0aWNrLyl7dGFyZ2V0PSJfYmxhbmsifSAgIHwgdG8gZXZhbHVhdGUgdGhlIHBlcmZvcm1hbmNlIG9mIG1vZGVscwpbYnJvb21dKGh0dHBzOi8vd3d3LnRpZHl2ZXJzZS5vcmcvYmxvZy8yMDE4LzA3L2Jyb29tLTAtNS0wLyl7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIGdldCB0aWR5IG91dHB1dCBmb3Igb3VyIG1vZGVsIGZpdCBhbmQgcGVyZm9ybWFuY2UKW2dncGxvdDJdKGh0dHBzOi8vZ2dwbG90Mi50aWR5dmVyc2Uub3JnLyl7dGFyZ2V0PSJfYmxhbmsifSAgICB8IHRvIG1ha2UgdmlzdWFsaXphdGlvbnMgd2l0aCBtdWx0aXBsZSBsYXllcnMKW2RpYWxzXShodHRwczovL3d3dy50aWR5dmVyc2Uub3JnL2Jsb2cvMjAxOS8xMC9kaWFscy0wLTAtMy8pe3RhcmdldD0iX2JsYW5rIn0gfCB0byBzcGVjaWZ5IGh5cGVyLXBhcmFtZXRlciB0dW5pbmcKW3R1bmVdKGh0dHBzOi8vdHVuZS50aWR5bW9kZWxzLm9yZy8pe3RhcmdldD0iX2JsYW5rIn0gfCB0byBwZXJmb3JtIGNyb3NzIHZhbGlkYXRpb24sIHR1bmUgaHlwZXItcGFyYW1ldGVycywgYW5kIGdldCBwZXJmb3JtYW5jZSBtZXRyaWNzClt3b3JrZmxvd3NdKGh0dHBzOi8vd3d3LnJkb2N1bWVudGF0aW9uLm9yZy9wYWNrYWdlcy93b3JrZmxvd3MvdmVyc2lvbnMvMC4xLjEpe3RhcmdldD0iX2JsYW5rIn18IHRvIGNyZWF0ZSBtb2RlbGluZyB3b3JrZmxvdyB0byBzdHJlYW1saW5lIHRoZSBtb2RlbGluZyBwcm9jZXNzClt2aXBdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy92aXAvdmlwLnBkZil7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIGNyZWF0ZSB2YXJpYWJsZSBpbXBvcnRhbmNlIHBsb3RzCltyYW5kb21Gb3Jlc3RdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9yYW5kb21Gb3Jlc3QvcmFuZG9tRm9yZXN0LnBkZil7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIHBlcmZvcm0gdGhlIHJhbmRvbSBmb3Jlc3QgYW5hbHlzaXMKW3N0cmluZ3JdKGh0dHBzOi8vc3RyaW5nci50aWR5dmVyc2Uub3JnL2FydGljbGVzL3N0cmluZ3IuaHRtbCl7dGFyZ2V0PSJfYmxhbmsifSAgICB8IHRvIG1hbmlwdWxhdGUgdGhlIHRleHQgdGhlIG1hcCBkYXRhClt0aWR5cl0oaHR0cHM6Ly90aWR5ci50aWR5dmVyc2Uub3JnLyl7dGFyZ2V0PSJfYmxhbmsifSAgICAgIHwgdG8gc2VwYXJhdGUgZGF0YSB3aXRoaW4gYSBjb2x1bW4gaW50byBtdWx0aXBsZSBjb2x1bW5zCltybmF0dXJhbGVhcnRoXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvcm5hdHVyYWxlYXJ0aC9SRUFETUUuaHRtbCl7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIGdldCB0aGUgZ2VvbWV0cnkgZGF0YSBmb3IgdGhlIGVhcnRoIHRvIHBsb3QgdGhlIFVTClttYXBzXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvbWFwcy9tYXBzLnBkZil7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIGdldCBtYXAgZGF0YWJhc2UgZGF0YSBhYm91dCBjb3VudGllcyB0byBkcmF3IHRoZW0gb24gb3VyIFVTIG1hcApbc2ZdKGh0dHBzOi8vci1zcGF0aWFsLmdpdGh1Yi5pby9zZi8pe3RhcmdldD0iX2JsYW5rIn0gfCB0byBjb252ZXJ0IHRoZSBtYXAgZGF0YSBpbnRvIGEgZGF0YSBmcmFtZQpbbHdnZW9tXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvbHdnZW9tL2x3Z2VvbS5wZGYpe3RhcmdldD0iX2JsYW5rIn0gfCB0byB1c2UgdGhlIGBzZmAgZnVuY3Rpb24gdG8gY29udmVydCBtYXAgZ2VvZ3JhcGhpY2FsIGRhdGEKW3JnZW9zXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvcmdlb3Mvcmdlb3MucGRmKXt0YXJnZXQ9Il9ibGFuayJ9IHwgdG8gdXNlIGdlb21ldHJ5IGRhdGEKW3BhdGNod29ya10oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL3BhdGNod29yay9wYXRjaHdvcmsucGRmKXt0YXJnZXQ9Il9ibGFuayJ9IHwgdG8gYWxsb3cgcGxvdHMgdG8gYmUgY29tYmluZWQKX19fCgoKVGhlIGZpcnN0IHRpbWUgd2UgdXNlIGEgZnVuY3Rpb24sIHdlIHdpbGwgdXNlIHRoZSBgOjpgIHRvIGluZGljYXRlIHdoaWNoIHBhY2thZ2Ugd2UgYXJlIHVzaW5nLiAKVW5sZXNzIHdlIGhhdmUgb3ZlcmxhcHBpbmcgZnVuY3Rpb24gbmFtZXMsIHRoaXMgaXMgbm90IG5lY2Vzc2FyeSwgYnV0IHdlIHdpbGwgaW5jbHVkZSBpdCBoZXJlIHRvIGJlIGluZm9ybWF0aXZlIGFib3V0IHdoZXJlIHRoZSBmdW5jdGlvbnMgd2Ugd2lsbCB1c2UgY29tZSBmcm9tLgoKCiMjIENvbnRleHQKKioqCgpUaGUgW1N0YXRlIG9mIEdsb2JhbCBBaXJdKGh0dHBzOi8vd3d3LnN0YXRlb2ZnbG9iYWxhaXIub3JnLyl7dGFyZ2V0PSJfYmxhbmsifSBpcyBhIHJlcG9ydCByZWxlYXNlZCBldmVyeSB5ZWFyIHRvIGNvbW11bmljYXRlIHRoZSBpbXBhY3Qgb2YgYWlyIHBvbGx1dGlvbiBvbiBwdWJsaWMgaGVhbHRoLiAKClRoZSBbU3RhdGUgb2YgR2xvYmFsIEFpciAyMDE5IHJlcG9ydF0oaHR0cHM6Ly93d3cuc3RhdGVvZmdsb2JhbGFpci5vcmcvc2l0ZXMvZGVmYXVsdC9maWxlcy9zb2dhXzIwMTlfcmVwb3J0LnBkZil7dGFyZ2V0PSJfYmxhbmsifQp3aGljaCB1c2VzIGRhdGEgZnJvbSAyMDE3IHN0YXRlZCB0aGF0OgoKPiBBaXIgcG9sbHV0aW9uIGlzIHRoZSAqKmZpZnRoKiogbGVhZGluZyByaXNrIGZhY3RvciBmb3IgbW9ydGFsaXR5IHdvcmxkd2lkZS4gSXQgaXMgcmVzcG9uc2libGUgZm9yIG1vcmUKZGVhdGhzIHRoYW4gbWFueSBiZXR0ZXIta25vd24gcmlzayBmYWN0b3JzIHN1Y2ggYXMgbWFsbnV0cml0aW9uLCBhbGNvaG9sIHVzZSwgYW5kIHBoeXNpY2FsIGluYWN0aXZpdHkuCkVhY2ggeWVhciwgKiptb3JlKiogcGVvcGxlIGRpZSBmcm9tIGFpciBwb2xsdXRpb27igJNyZWxhdGVkIGRpc2Vhc2UgdGhhbiBmcm9tIHJvYWQgKip0cmFmZmljIGluanVyaWVzKiogb3IgKiptYWxhcmlhKiouCgo8cCBhbGlnbj0iY2VudGVyIj4KPGltZyB3aWR0aD0iNjAwIiBzcmM9Imh0dHBzOi8vd3d3LmhlYWx0aGVmZmVjdHMub3JnL3NpdGVzL2RlZmF1bHQvZmlsZXMvU29HQS1GaWd1cmVzLTAxLmpwZyI+CjwvcD4KCiMjIyMjIFtbc291cmNlXV0oaHR0cHM6Ly93d3cuc3RhdGVvZmdsb2JhbGFpci5vcmcvc2l0ZXMvZGVmYXVsdC9maWxlcy9zb2dhXzIwMTlfcmVwb3J0LnBkZil7dGFyZ2V0PSJfYmxhbmsifQoKVGhlIHJlcG9ydCBhbHNvIHN0YXRlZCB0aGF0OgoKPiBJbiAyMDE3LCBhaXIgcG9sbHV0aW9uIGlzIGVzdGltYXRlZCB0byBoYXZlIGNvbnRyaWJ1dGVkIHRvIGNsb3NlIHRvIDUgbWlsbGlvbgpkZWF0aHMgZ2xvYmFsbHkg4oCUIG5lYXJseSAqKjEgaW4gZXZlcnkgMTAgZGVhdGhzKiouCgpgYGB7ciwgZWNobyA9IEZBTFNFLCBvdXQud2lkdGg9IjgwMHB4In0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1nIiwiMjAxN2RlYXRocy5wbmciKSkKYGBgCgojIyMjIyBbW3NvdXJjZV1dKGh0dHBzOi8vd3d3LnN0YXRlb2ZnbG9iYWxhaXIub3JnL3NpdGVzL2RlZmF1bHQvZmlsZXMvc29nYV8yMDE5X2ZhY3Rfc2hlZXQucGRmKXt0YXJnZXQ9Il9ibGFuayJ9CgpUaGUgW1N0YXRlIG9mIEdsb2JhbCBBaXIgMjAxOCByZXBvcnRdKGh0dHBzOi8vd3d3LnN0YXRlb2ZnbG9iYWxhaXIub3JnL3NpdGVzL2RlZmF1bHQvZmlsZXMvc29nYS0yMDE4LXJlcG9ydC5wZGYpe3RhcmdldD0iX2JsYW5rIn0gdXNpbmcgZGF0YSBmcm9tIDIwMTYgd2hpY2ggc2VwYXJhdGVkIGRpZmZlcmVudCB0eXBlcyBvZiBhaXIgcG9sbHV0aW9uLCBmb3VuZCB0aGF0ICoqcGFydGljdWxhdGUgcG9sbHV0aW9uIHdhcyBwYXJ0aWN1bGFybHkgYXNzb2NpYXRlZCB3aXRoIG1vcnRhbGl0eSoqLgoKYGBge3IsIGVjaG8gPSBGQUxTRSwgb3V0LndpZHRoPSI4MDBweCJ9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltZyIsIjIwMTdtb3J0YWxpdHkucG5nIikpCmBgYAoKVGhlIDIwMTkgcmVwb3J0IHNob3dzIHRoYXQgdGhlIGhpZ2hlc3QgbGV2ZWxzIG9mIGZpbmUgcGFydGljdWxhdGUgcG9sbHV0aW9uIG9jY3VycyBpbiBBZnJpY2EgYW5kIEFzaWEgYW5kIHRoYXQ6Cgo+IE1vcmUgdGhhbiAqKjkwJSoqIG9mIHBlb3BsZSB3b3JsZHdpZGUgbGl2ZSBpbiBhcmVhcyAqKmV4Y2VlZGluZyoqIHRoZSBXb3JsZCBIZWFsdGggT3JnYW5pemF0aW9uIChXSE8pICoqR3VpZGVsaW5lKiogZm9yIGhlYWx0aHkgYWlyLiBNb3JlIHRoYW4gaGFsZiBsaXZlIGluIGFyZWFzIHRoYXQgZG8gbm90IGV2ZW4gbWVldCBXSE8ncyBsZWFzdC1zdHJpbmdlbnQgYWlyIHF1YWxpdHkgdGFyZ2V0LgoKYGBge3IsIGVjaG8gPSBGQUxTRSwgb3V0LndpZHRoPSI4MDBweCJ9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltZyIsIlBNd29ybGQucG5nIikpCmBgYAoKIyMjIyMgW1tzb3VyY2VdXShodHRwczovL3d3dy5zdGF0ZW9mZ2xvYmFsYWlyLm9yZy9zaXRlcy9kZWZhdWx0L2ZpbGVzL3NvZ2FfMjAxOV9mYWN0X3NoZWV0LnBkZil7dGFyZ2V0PSJfYmxhbmsifQoKTG9va2luZyBhdCB0aGUgVVMgc3BlY2lmaWNhbGx5LCBhaXIgcG9sbHV0aW9uIGxldmVscyBhcmUgZ2VuZXJhbGx5IGltcHJvdmluZywgd2l0aCBkZWNsaW5pbmcgbmF0aW9uYWwgYWlyIHBvbGx1dGFudCBjb25jZW50cmF0aW9uIGF2ZXJhZ2VzIGFzIHNob3duIGZyb20gdGhlIDIwMTkgWypPdXIgTmF0aW9uJ3MgQWlyKl0oaHR0cHM6Ly9naXNwdWIuZXBhLmdvdi9haXIvdHJlbmRzcmVwb3J0LzIwMTkvI2hvbWUpe3RhcmdldD0iX2JsYW5rIn0gcmVwb3J0IGZyb20gdGhlIFVTIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSk6IAoKYGBge3IsIGVjaG8gPSBGQUxTRX0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1nIiwgIlVTLnBuZyIpKQpgYGAKCiMjIyMjIFtbc291cmNlXV0oaHR0cHM6Ly9naXNwdWIuZXBhLmdvdi9haXIvdHJlbmRzcmVwb3J0LzIwMTkvZG9jdW1lbnRhdGlvbi9BaXJUcmVuZHNfRmx5ZXIucGRmKXt0YXJnZXQ9Il9ibGFuayJ9CgpIb3dldmVyLCBhaXIgcG9sbHV0aW9uICoqY29udGludWVzIHRvIGNvbnRyaWJ1dGUgdG8gaGVhbHRoIHJpc2sgZm9yIEFtZXJpY2FucyoqLCBpbiBwYXJ0aWN1bGFyIGluICoqcmVnaW9ucyB3aXRoIGhpZ2hlciB0aGFuIG5hdGlvbmFsIGF2ZXJhZ2UgcmF0ZXMqKiBvZiBwb2xsdXRpb24gdGhhdCBhY3R1YWxseSBhdCB0aW1lIGV4Y2VlZCB0aGUgV0hPJ3MgcmVjb21tZW5kZWQgbGV2ZWwuIApUaHVzLCBpdCBpcyBpbXBvcnRhbnQgdG8gb2J0YWluIGhpZ2ggc3BhdGlhbCBncmFudWxhcml0eSBpbiBlc3RpbWF0ZXMgb2YgYWlyIHBvbGx1dGlvbiBpbiBvcmRlciB0byBpZGVudGlmeSBsb2NhdGlvbnMgd2hlcmUgcG9wdWxhdGlvbnMgYXJlIGV4cGVyaWVuY2luZyBoYXJtZnVsIGxldmVscyBvZiBleHBvc3VyZS4KCllvdSBjYW4gc2VlIHRoYXQgY3VycmVudCBhaXIgcXVhbGl0eSBjb25kaXRpb25zIGF0IHRoaXMgW3dlYnNpdGVdKGh0dHBzOi8vYXFpY24ub3JnL2NpdHkvdXNhLyl7dGFyZ2V0PSJfYmxhbmsifSBhbmQgeW91IHdpbGwgbm90aWNlIHZhcmlhdGlvbiBhY3Jvc3MgZGlmZmVyZW50IGNpdGllcy4KCkZvciBleGFtcGxlLCBoZXJlIGFyZSB0aGUgY29uZGl0aW9ucyBpbiBUb3Bla2EgS2Fuc2FzIGF0IHRoZSB0aW1lIHRoaXMgY2FzZSBzdHVkeSB3YXMgY3JlYXRlZDoKCmBgYHtyLCBlY2hvID0gRkFMU0V9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltZyIsICJLYW5zYXMucG5nIikpCmBgYAoKSXQgcmVwb3J0cyBwYXJ0aWN1bGF0ZSB2YWx1ZXMgdXNpbmcgd2hhdCBpcyBjYWxsZWQgdGhlIFtBaXIgUXVhbGl0eSBJbmRleF0oaHR0cHM6Ly93d3cuYWlybm93Lmdvdi9pbmRleC5jZm0/YWN0aW9uPWFxaWJhc2ljcy5hcWkpe3RhcmdldD0iX2JsYW5rIn0gKEFRSSkuClRoaXMgW2NhbGN1bGF0b3JdKGh0dHBzOi8vYWlybm93Lmdvdi9pbmRleC5jZm0/YWN0aW9uPWFpcm5vdy5jYWxjdWxhdG9yKXt0YXJnZXQ9Il9ibGFuayJ9IGluZGljYXRlcyB0aGF0IDExNCBBUUkgaXMgZXF1aXZhbGVudCB0byA0MC43IHVnL21eM14gYW5kIGlzIGNvbnNpZGVyZWQgdW5oZWFsdGh5IGZvciBzZW5zaXRpdmUgaW5kaXZpZHVhbHMuClRodXMsIHNvbWUgYXJlYXMgZXhjZWVkIHRoZSBXSE8gYW5udWFsIGV4cG9zdXJlIGd1aWRlbGluZSAoMTAgdWcvbV4zXikgYW5kIHRoaXMgbWF5IGFkdmVyc2VseSBhZmZlY3QgdGhlIGhlYWx0aCBvZiBwZW9wbGUgbGl2aW5nIGluIHRoZXNlIGxvY2F0aW9ucy4KCkFkdmVyc2UgaGVhbHRoIGVmZmVjdHMgaGF2ZSBiZWVuIGFzc29jaWF0ZWQgd2l0aCBwb3B1bGF0aW9ucyBleHBlcmllbmNpbmcgaGlnaGVyIHBvbGx1dGlvbiBleHBvc3VyZSBkZXNwaXRlIHRoZSBsZXZlbHMgYmVpbmcgYmVsb3cgc3VnZ2VzdGVkIGd1aWRlbGluZXMuIApBbHNvLCBpdCBhcHBlYXJzIHRoYXQgdGhlIGNvbXBvc2l0aW9uIG9mIHRoZSBwYXJ0aWN1bGF0ZSBtYXRlciBhbmQgdGhlIGluZmx1ZW5jZSBvZiBvdGhlciBkZW1vZ3JhcGhpYyBmYWN0b3JzIG1heSBtYWtlIHNwZWNpZmljIHBvcHVsYXRpb25zIG1vcmUgYXQgcmlzayBmb3IgYWR2ZXJzZSBoZWFsdGggZWZmZWN0cyBkdWUgdG8gYWlyIHBvbGx1dGlvbi4gCkZvciBleGFtcGxlLCBzZWUgdGhpcyBbYXJ0aWNsZV0oaHR0cHM6Ly93d3cubmVqbS5vcmcvZG9pL2Z1bGwvMTAuMTA1Ni9ORUpNb2ExNzAyNzQ3KXt0YXJnZXQ9Il9ibGFuayJ9IGZvciBtb3JlIGRldGFpbHMuCgpUaGUgbW9uaXRvciBkYXRhIHRoYXQgd2Ugd2lsbCB1c2UgaW4gdGhpcyBjYXNlIHN0dWR5IGNvbWUgZnJvbSBhIHN5c3RlbSBvZiBtb25pdG9ycyBpbiB3aGljaCByb3VnaGx5IDkwJSBhcmUgbG9jYXRlZCB3aXRoaW4gY2l0aWVzLiAKSGVuY2UsIHRoZXJlIGlzIGFuICoqZXF1aXR5IGlzc3VlKiogaW4gdGVybXMgb2YgY2FwdHVyaW5nIHRoZSBhaXIgcG9sbHV0aW9uIGxldmVscyBvZiBtb3JlIHJ1cmFsIGFyZWFzLiAKVG8gZ2V0IGEgYmV0dGVyIHNlbnNlIG9mIHRoZSBwb2xsdXRpb24gZXhwb3N1cmVzIGZvciB0aGUgaW5kaXZpZHVhbHMgbGl2aW5nIGluIHRoZXNlIGFyZWFzLCBtZXRob2RzIGxpa2UgbWFjaGluZSBsZWFybmluZyBjYW4gYmUgdXNlZnVsIHRvIGVzdGltYXRlIGFpciBwb2xsdXRpb24gbGV2ZWxzIGluICoqYXJlYXMgd2l0aCBsaXR0bGUgdG8gbm8gbW9uaXRvcmluZyoqLiAKU3BlY2lmaWNhbGx5LCB0aGVzZSBtZXRob2RzIGNhbiBiZSB1c2VkIHRvIGVzdGltYXRlIGFpciBwb2xsdXRpb24gaW4gdGhlc2UgbG93IG1vbml0b3JpbmcgYXJlYXMgc28gdGhhdCB3ZSBjYW4gbWFrZSBhIG1hcCBsaWtlIHRoaXMgd2hlcmUgd2UgaGF2ZSBhbm51YWwgZXN0aW1hdGVzIGZvciBhbGwgb2YgdGhlIGNvbnRpZ3VvdXMgVVM6Cgo8cCBhbGlnbj0iY2VudGVyIj4KICA8aW1nIHdpZHRoPSI2MDAiIHNyYz0iaHR0cHM6Ly9hcmMtYW5nbGVyZmlzaC13YXNocG9zdC1wcm9kLXdhc2hwb3N0LnMzLmFtYXpvbmF3cy5jb20vcHVibGljL1NBV09FR0JYTVZHUTdBUzVQWjZVVU9YNkZZLnBuZyI+CjwvcD4KCiMjIyMjIFtbc291cmNlXV0oaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS91cmw/c2E9aSZ1cmw9aHR0cHMlM0ElMkYlMkZ3d3cud2FzaGluZ3RvbnBvc3QuY29tJTJGYnVzaW5lc3MlMkYyMDE5JTJGMTAlMkYyMyUyRmFpci1wb2xsdXRpb24taXMtZ2V0dGluZy13b3JzZS1kYXRhLXNob3ctbW9yZS1wZW9wbGUtYXJlLWR5aW5nJTJGJnBzaWc9QU92VmF3M3YtWkRUQlBuTFAyTVl0S2YzVW5kaiZ1c3Q9MTU4NTc4NDQ3OTA2ODAwMCZzb3VyY2U9aW1hZ2VzJmNkPXZmZSZ2ZWQ9MENBSVFqUnhxRndvVENQQ3luOWZ4eGVnQ0ZRQUFBQUFkQUFBQUFCQWQpe3RhcmdldD0iX2JsYW5rIn0KClRoaXMgaXMgd2hhdCB3ZSBhaW0gdG8gYWNoaWV2ZSBpbiB0aGlzIGNhc2Ugc3R1ZHkuCgojIyBMaW1pdGF0aW9ucwoqKioKClRoZXJlIGFyZSBzb21lIGltcG9ydGFudCBjb25zaWRlcmF0aW9ucyByZWdhcmRpbmcgdGhlIGRhdGEgYW5hbHlzaXMgaW4gdGhpcyBjYXNlIHN0dWR5IHRvIGtlZXAgaW4gbWluZDogCgoxLiBUaGUgZGF0YSBkbyBub3QgaW5jbHVkZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgY29tcG9zaXRpb24gb2YgcGFydGljdWxhdGUgbWF0ZXIuIERpZmZlcmVudCB0eXBlcyBvZiBwYXJ0aWN1bGF0ZXMgbWF5IGJlIG1vcmUgYmVuaWduIG9yIGRlbGV0ZXJpb3VzIGZvciBoZWFsdGggb3V0Y29tZXMuCgoyLiBPdXRkb29yIHBvbGx1dGlvbiBsZXZlbHMgYXJlIG5vdCBuZWNlc3NhcmlseSBhbiBpbmRpY2F0aW9uIG9mIGluZGl2aWR1YWwgZXhwb3N1cmVzLiBQZW9wbGUgc3BlbmQgZGlmZmVyaW5nIGFtb3VudHMgb2YgdGltZSBpbmRvb3JzIGFuZCBvdXRkb29ycyBhbmQgYXJlIGV4cG9zZWQgdG8gZGlmZmVyZW50IHBvbGx1dGlvbiBsZXZlbHMgaW5kb29ycy4gUmVzZWFyY2hlcnMgYXJlIG5vdyBkZXZlbG9waW5nIHBlcnNvbmFsIG1vbml0b3Jpbmcgc3lzdGVtcyB0byB0cmFjayBhaXIgcG9sbHV0aW9uIGxldmVscyBvbiB0aGUgcGVyc29uYWwgbGV2ZWwuCgozLiBPdXIgYW5hbHlzaXMgd2lsbCB1c2UgYW5udWFsIG1lYW4gZXN0aW1hdGVzIG9mIHBvbGx1dGlvbiBsZXZlbHMsIGJ1dCB0aGVzZSBjYW4gdmFyeSBncmVhdGx5IGJ5IHNlYXNvbiwgZGF5IGFuZCBldmVuIGhvdXIuIFRoZXJlIGFyZSBkYXRhIHNvdXJjZXMgdGhhdCBoYXZlIGZpbmVyIGxldmVscyBvZiB0ZW1wb3JhbCBkYXRhLCBob3dldmVyIHdlIGFyZSBpbnRlcmVzdGVkIGluIGxvbmcgdGVybSBleHBvc3VyZXMsIGFzIHRoZXNlIGFwcGVhciB0byBiZSB0aGUgbW9zdCBpbmZsdWVudGlhbCBmb3IgaGVhbHRoIG91dGNvbWVzLCBzbyB3ZSBjaG9zZSB0byB1c2UgYW5udWFsIGxldmVsIGRhdGEuIAoKCiMgKipXaGF0IGFyZSB0aGUgZGF0YT8qKiB7I3doYXRhcmV0aGVkYXRhfQoqKioKCldoZW4gdXNpbmcgbWFjaGluZSBsZWFybmluZyBmb3IgcHJlZGljdGlvbiwgdGhlcmUgYXJlIHR3byBtYWluIHR5cGVzIG9mIGRhdGEgb2YgaW50ZXJlc3Q6CgoxLiBBbiAqKmNvbnRpbnVvdXMqKiBvdXRjb21lIHZhcmlhYmxlIHRoYXQgd2Ugd2FudCB0byBwcmVkaWN0IAoyLiBBIHNldCBvZiBmZWF0dXJlKHMpIChvciBwcmVkaWN0b3IgdmFyaWFibGVzKSB0aGF0IHdlIHVzZSB0byBwcmVkaWN0IHRoZSBvdXRjb21lIHZhcmlhYmxlCgpUaGUgKipvdXRjb21lIHZhcmlhYmxlKiogaXMgd2hhdCBhcmUgdHJ5aW5nIHRvICoqcHJlZGljdCoqLiAKVG8gYnVpbGQgKG9yIHRyYWluKSBvdXIgbW9kZWwsIHdlIHVzZSBib3RoIHRoZSBvdXRjb21lIGFuZCBmZWF0dXJlcy4KVGhlIGdvYWwgaXMgdG8gaWRlbnRpZnkgaW5mb3JtYXRpdmUgZmVhdHVyZXMgdGhhdCBjYW4gZXhwbGFpbiBhIGxhcmdlIGFtb3VudCBvZiB2YXJpYXRpb24gaW4gb3VyIG91dGNvbWUgdmFyaWFibGUuIApVc2luZyB0aGlzIG1vZGVsLCB3ZSBjYW4gdGhlbiBwcmVkaWN0IHRoZSBvdXRjb21lIGZyb20gbmV3IG9ic2VydmF0aW9ucyB3aXRoIHRoZSBzYW1lIGZlYXR1cmVzIHdoZXJlIGhhdmUgbm90IG9ic2VydmVkIHRoZSBvdXRjb21lLiAKCkFzIGEgc2ltcGxlIGV4YW1wbGUsIGltYWdpbmUgdGhhdCB3ZSBoYXZlIGRhdGEgYWJvdXQgdGhlIHNhbGVzIGFuZCBjaGFyYWN0ZXJpc3RpY3Mgb2YgY2FycyBmcm9tIGxhc3QgeWVhciBhbmQgd2Ugd2FudCB0byBwcmVkaWN0IHdoaWNoIGNhcnMgbWlnaHQgc2VsbCB3ZWxsIHRoaXMgeWVhci4gCldlIGRvIG5vdCBoYXZlIHRoZSBzYWxlcyBkYXRhIHlldCBmb3IgdGhpcyB5ZWFyLCBidXQgd2UgZG8ga25vdyB0aGUgY2hhcmFjdGVyaXN0aWNzIG9mIG91ciBjYXJzIGZvciB0aGlzIHllYXIuIApXZSBjYW4gYnVpbGQgYSBtb2RlbCBvZiB0aGUgY2hhcmFjdGVyaXN0aWNzIHRoYXQgZXhwbGFpbmVkIHNhbGVzIGxhc3QgeWVhciB0byBlc3RpbWF0ZSB3aGF0IGNhcnMgbWlnaHQgc2VsbCB3ZWxsIHRoaXMgeWVhci4gCkluIHRoaXMgY2FzZSwgb3VyIG91dGNvbWUgdmFyaWFibGUgaXMgdGhlIHNhbGVzIG9mIGNhcnMsIHdoaWxlIHRoZSBkaWZmZXJlbnQgY2hhcmFjdGVyaXN0aWNzIG9mIHRoZSBjYXJzIG1ha2UgdXAgb3VyIGZlYXR1cmVzLgoKIyMjIFN0YXJ0IHdpdGggYSBxdWVzdGlvbgoKVGhpcyBpcyB0aGUgbW9zdCBjb21tb25seSBtaXNzZWQgc3RlcCB3aGVuIGRldmVsb3BpbmcgYSBtYWNoaW5lIGxlYXJuaW5nIGFsZ29yaXRobS4gCk1hY2hpbmUgbGVhcm5pbmcgY2FuIHZlcnkgZWFzaWx5IGJlIHR1cm5lZCBpbnRvIGFuIGVuZ2luZWVyaW5nIHByb2JsZW0uIApKdXN0IGR1bXAgdGhlIG91dGNvbWUgYW5kIHRoZSBmZWF0dXJlcyBpbnRvIGEgYmxhY2sgYm94IGFsZ29yaXRobSBhbmQgdmlvbGEhIApCdXQgdGhpcyBraW5kIG9mIHRoaW5raW5nIGNhbiBsZWFkIHRvIG1ham9yIHByb2JsZW1zLiBJbiBnZW5lcmFsIGdvb2QgbWFjaGluZSBsZWFybmluZyBxdWVzdGlvbnM6CgoxLiBIYXZlIGEgcGxhdXNpYmxlIGV4cGxhbmF0aW9uIGZvciB3aHkgdGhlIGZlYXR1cmVzIHByZWRpY3QgdGhlIG91dGNvbWUuIAoyLiBDb25zaWRlciBwb3RlbnRpYWwgdmFyaWF0aW9uIGluIGJvdGggdGhlIGZlYXR1cmVzIGFuZCB0aGUgb3V0Y29tZSBvdmVyIHRpbWUKMy4gQXJlIGNvbnNpc3RlbnRseSByZS1ldmFsdWF0ZWQgb24gY3JpdGVyaWEgMSBhbmQgMiBvdmVyIHRpbWUuIAoKSW4gdGhpcyBjYXNlIHN0dWR5LCB3ZSB3YW50IHRvICoqcHJlZGljdCoqIGFpciBwb2xsdXRpb24gbGV2ZWxzLiAKVG8gYnVpbGQgdGhpcyBtYWNoaW5lIGxlYXJuaW5nIGFsZ29yaXRobSwgb3VyICoqb3V0Y29tZSB2YXJpYWJsZSoqIGlzIGZpbmUgcGFydGljdWxhdGUgbWF0dGVyIChQTX4yLjV+KSBjYXB0dXJlZCBmcm9tIGFpciBwb2xsdXRpb24gbW9uaXRvcnMgaW4gdGhlIGNvbnRpZ3VvdXMgVVMgZnJvbSAyMDA4LiAKT3VyICoqZmVhdHVyZXMqKiAob3IgcHJlZGljdG9yIHZhcmlhYmxlcykgaW5jbHVkZSBkYXRhIGFib3V0IHBvcHVsYXRpb24gZGVuc2l0eSwgcm9hZCBkZW5zaXR5LCB1cmJhbml6YXRpb24gbGV2ZWxzLCBhbmQgTkFTQSBzYXRlbGxpdGUgZGF0YS4gCgpBbGwgb2Ygb3VyIGRhdGEgd2FzIHByZXZpb3VzbHkgY29sbGVjdGVkIGJ5IGEgW3Jlc2VhcmNoZXJdKGh0dHA6Ly93d3cuYmlvc3RhdC5qaHNwaC5lZHUvfnJwZW5nLykgYXQgdGhlIFtKb2hucyBIb3BraW5zIFNjaG9vbCBvZiBQdWJsaWMgSGVhbHRoXShodHRwczovL3d3dy5qaHNwaC5lZHUvKSB3aG8gc3R1ZGllcyBhaXIgcG9sbHV0aW9uIGFuZCBjbGltYXRlIGNoYW5nZS4gCgoKIyMjIE91ciBvdXRjb21lIHZhcmlhYmxlCgpUaGUgbW9uaXRvciBkYXRhIHRoYXQgd2Ugd2lsbCBiZSB1c2luZyBjb21lcyBmcm9tICoqW2dyYXZpbWV0cmljIG1vbml0b3JzXShodHRwczovL3B1YmxpY2xhYi5vcmcvd2lraS9maWx0ZXItcG0pe3RhcmdldD0iX2JsYW5rIn0qKiAoc2VlIHBpY3R1cmUgYmVsb3cpIG9wZXJhdGVkIGJ5IHRoZSBVUyBbRW5pdm9ybm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKV0oaHR0cHM6Ly93d3cuZXBhLmdvdi8pe3RhcmdldD0iX2JsYW5rIn0uCgpgYGB7ciwgZWNobyA9IEZBTFNFLCBvdXQud2lkdGg9IjEwMHB4In0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1nIiwibW9uaXRvci5wbmciKSkKYGBgCgpUaGVzZSBtb25pdG9ycyB1c2UgYSBmaWx0cmF0aW9uIHN5c3RlbSB0byBzcGVjaWZpY2FsbHkgY2FwdHVyZSBmaW5lIHBhcnRpY3VsYXRlIG1hdHRlci4gCgpgYGB7ciwgZWNobyA9IEZBTFNFLCBvdXQud2lkdGg9IjE1MHB4In0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1nIiwiZmlsdGVyLnBuZyIpKQpgYGAKCiMjIyMjIFtbc291cmNlXV0oaHR0cHM6Ly9wdWJsaWNsYWIub3JnL3dpa2kvZmlsdGVyLXBtKXt0YXJnZXQ9Il9ibGFuayJ9CgpUaGUgd2VpZ2h0IG9mIHRoaXMgcGFydGljdWxhdGUgbWF0dGVyIGlzIG1hbnVhbGx5IG1lYXN1cmVkIGRhaWx5IG9yIHdlZWtseS4gCkZvciB0aGUgRVBBIHN0YW5kYXJkIG9wZXJhdGluZyBwcm9jZWR1cmUgZm9yIFBNIGdyYXZpbWV0cmljIGFuYWx5c2lzIGluIDIwMDgsIHdlIHJlZmVyIHRoZSByZWFkZXIgdG8gW2hlcmVdKGh0dHBzOi8vd3d3My5lcGEuZ292L3R0bmFtdGkxL2ZpbGVzL2FtYmllbnQvcG0yNS9zcGVjL1JUSUdyYXZNYXNzU09QRklOQUwucGRmKXt0YXJnZXQ9Il9ibGFuayJ9LgoKPGRldGFpbHM+PHN1bW1hcnk+Rm9yIG1vcmUgb24gR3JhdmltZXRyaWMgYW5hbHlzaXMsIHlvdSBjYW4gZXhwYW5kIGhlcmUgPC9zdW1tYXJ5PgoKR3JhdmltZXRyaWMgYW5hbHlzaXMgaXMgYWxzbyB1c2VkIGZvciBbZW1pc3Npb24gdGVzdGluZ10oaHR0cHM6Ly93d3cubXQuY29tL3VzL2VuL2hvbWUvYXBwbGljYXRpb25zL0xhYm9yYXRvcnlfd2VpZ2hpbmcvZW1pc3Npb25zLXRlc3RpbmctcGFydGljdWxhdGUtbWF0dGVyLmh0bWwpe3RhcmdldD0iX2JsYW5rIn0uIApUaGUgc2FtZSBpZGVhIGFwcGxpZXM6IGEgZnJlc2ggZmlsdGVyIGlzIGFwcGxpZWQgYW5kIHRoZSBkZXNpcmVkIGFtb3VudCBvZiB0aW1lIHBhc3NlcywgdGhlbiB0aGUgZmlsdGVyIGlzIHJlbW92ZWQgYW5kIHdlaWdoZWQuIAoKVGhlcmUgYXJlIFtvdGhlciBtb25pdG9yaW5nIHN5c3RlbXNdKGh0dHBzOi8vd3d3LnNlbnNpcmlvbi5jb20vZW4vYWJvdXQtdXMvbmV3c3Jvb20vc2Vuc2lyaW9uLXNwZWNpYWxpc3QtYXJ0aWNsZXMvcGFydGljdWxhdGUtbWF0dGVyLXNlbnNpbmctZm9yLWFpci1xdWFsaXR5LW1lYXN1cmVtZW50cy8pe3RhcmdldD0iX2JsYW5rIn0gdGhhdCBjYW4gcHJvdmlkZSBob3VybHkgbWVhc3VyZW1lbnRzLCBidXQgd2Ugd2lsbCBub3QgYmUgdXNpbmcgZGF0YSBmcm9tIHRoZXNlIG1vbml0b3JzIGluIG91ciBhbmFseXNpcy4gCkdyYXZpbWV0cmljIGFuYWx5c2lzIGlzIGNvbnNpZGVyZWQgdG8gYmUgYW1vbmcgdGhlIG1vc3QgYWNjdXJhdGUgbWV0aG9kcyBmb3IgbWVhc3VyaW5nIHBhcnRpY3VsYXRlIG1hdHRlci4KCjwvZGV0YWlscz4KCkluIG91ciBkYXRhIHNldCwgdGhlIGB2YWx1ZWAgY29sdW1uIGluZGljYXRlcyB0aGUgUE1+Mi41fiBtb25pdG9yIGF2ZXJhZ2UgZm9yIDIwMDggaW4gbWFzcyBvZiBmaW5lIHBhcnRpY2xlcy92b2x1bWUgb2YgYWlyIGZvciA4NzYgZ3JhdmltZXRyaWMgbW9uaXRvcnMuIApUaGUgdW5pdHMgYXJlIG1pY3JvZ3JhbXMgb2YgZmluZSBwYXJ0aWN1bGF0ZSBtYXRlciAoUE0pIHRoYXQgaXMgbGVzcyB0aGFuIDIuNSBtaWNyb21ldGVycyBpbiBkaWFtZXRlciBwZXIgY3ViaWMgbWV0ZXIgb2YgYWlyIC0gbWFzcyBjb25jZW50cmF0aW9uICh1Zy9tXjNeKS4KUmVjYWxsIHRoZSBXSE8gZXhwb3N1cmUgZ3VpZGVsaW5lIGlzIDwgMTAgdWcvbV4zXiBvbiBhdmVyYWdlIGFubnVhbGx5IGZvciBQTX4yLjV+LgoKIyMjIE91ciBmZWF0dXJlcyAocHJlZGljdG9yIHZhcmlhYmxlcykgCgpUaGVyZSBhcmUgNDggZmVhdHVyZXMgd2l0aCB2YWx1ZXMgZm9yIGVhY2ggb2YgdGhlIDg3NiBtb25pdG9ycyAob2JzZXJ2YXRpb25zKS4gClRoZSBkYXRhIGNvbWVzIGZyb20gdGhlIFVTIFtFbml2b3JubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpXShodHRwczovL3d3dy5lcGEuZ292Lyl7dGFyZ2V0PSJfYmxhbmsifSwgdGhlIFtOYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24gKE5BU0EpXShodHRwczovL3d3dy5uYXNhLmdvdi8pe3RhcmdldD0iX2JsYW5rIn0sIHRoZSBVUyBbQ2Vuc3VzXShodHRwczovL3d3dy5jZW5zdXMuZ292L2Fib3V0L3doYXQvY2Vuc3VzLWF0LWEtZ2xhbmNlLmh0bWwpe3RhcmdldD0iX2JsYW5rIn0sIGFuZCB0aGUgW05hdGlvbmFsIENlbnRlciBmb3IgSGVhbHRoIFN0YXRpc3RpY3MgKE5DSFMpXShodHRwczovL3d3dy5jZGMuZ292L25jaHMvYWJvdXQvaW5kZXguaHRtKXt0YXJnZXQ9Il9ibGFuayJ9LgoKPGRldGFpbHM+PHN1bW1hcnk+IENsaWNrIGhlcmUgdG8gc2VlIGEgdGFibGUgYWJvdXQgdGhlIHNldCBvZiBmZWF0dXJlcyA8L3N1bW1hcnk+CgpWYXJpYWJsZSAgIHwgRGV0YWlscyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAotLS0tLS0tLS0tIHwtLS0tLS0tLS0tLS0tCioqaWQqKiAgfCBNb25pdG9yIG51bWJlciAgPGJyPiAtLSB0aGUgY291bnR5IG51bWJlciBpcyBpbmRpY2F0ZWQgYmVmb3JlIHRoZSBkZWNpbWFsIDxicj4gLS0gdGhlIG1vbml0b3IgbnVtYmVyIGlzIGluZGljYXRlZCBhZnRlciB0aGUgZGVjaW1hbCA8YnI+ICAqKkV4YW1wbGUqKjogMTA3My4wMDIzICBpcyBKZWZmZXJzb24gY291bnR5ICgxMDczKSBhbmQgLjAwMjMgb25lIG9mIDggbW9uaXRvcnMgCioqZmlwcyoqIHwgRmVkZXJhbCBpbmZvcm1hdGlvbiBwcm9jZXNzaW5nIHN0YW5kYXJkIG51bWJlciBmb3IgdGhlIGNvdW50eSB3aGVyZSB0aGUgbW9uaXRvciBpcyBsb2NhdGVkIDxicj4gLS0gNSBkaWdpdCBpZCBjb2RlIGZvciBjb3VudGllcyAoemVybyBpcyBvZnRlbiB0aGUgZmlyc3QgdmFsdWUgYW5kIHNvbWV0aW1lcyBpcyBub3Qgc2hvd24pIDxicj4gLS0gdGhlIGZpcnN0IDIgbnVtYmVycyBpbmRpY2F0ZSB0aGUgc3RhdGUgPGJyPiAtLSB0aGUgbGFzdCB0aHJlZSBudW1iZXJzIGluZGljYXRlIHRoZSBjb3VudHkgPGJyPiAgKipFeGFtcGxlKio6IEFsYWJhbWEncyBzdGF0ZSBjb2RlIGlzIDAxIGJlY2F1c2UgaXQgaXMgZmlyc3QgYWxwaGFiZXRpY2FsbHkgPGJyPiAobm90ZTogQWxhc2thIGFuZCBIYXdhaWkgYXJlIG5vdCBpbmNsdWRlZCBiZWNhdXNlIHRoZXkgYXJlIG5vdCBwYXJ0IG9mIHRoZSBjb250aWd1b3VzIFVTKSAgCioqTGF0KiogfCBMYXRpdHVkZSBvZiB0aGUgbW9uaXRvciBpbiBkZWdyZWVzICAKKipMb24qKiB8IExvbmdpdHVkZSBvZiB0aGUgbW9uaXRvciBpbiBkZWdyZWVzICAKKipzdGF0ZSoqIHwgU3RhdGUgd2hlcmUgdGhlIG1vbml0b3IgaXMgbG9jYXRlZAoqKmNvdW50eSoqIHwgQ291bnR5IHdoZXJlIHRoZSBtb25pdG9yIGlzIGxvY2F0ZWQKKipjaXR5KiogfCBDaXR5IHdoZXJlIHRoZSBtb25pdG9yIGlzIGxvY2F0ZWQKKipDTUFRKiogIHwgRXN0aW1hdGVkIHZhbHVlcyBvZiBhaXIgcG9sbHV0aW9uIGZyb20gYSBjb21wdXRhdGlvbmFsIG1vZGVsIGNhbGxlZCBbKipDb21tdW5pdHkgTXVsdGlzY2FsZSBBaXIgUXVhbGl0eSAoQ01BUSkqKl0oaHR0cHM6Ly93d3cuZXBhLmdvdi9jbWFxKXt0YXJnZXQ9Il9ibGFuayJ9IDxicj4gLS0gIEEgbW9uaXRvcmluZyBzeXN0ZW0gdGhhdCBzaW11bGF0ZXMgdGhlIHBoeXNpY3Mgb2YgdGhlIGF0bW9zcGhlcmUgdXNpbmcgY2hlbWlzdHJ5IGFuZCB3ZWF0aGVyIGRhdGEgdG8gcHJlZGljdCB0aGUgYWlyIHBvbGx1dGlvbiA8YnI+IC0tICoqKkRvZXMgbm90IHVzZSBhbnkgb2YgdGhlIFBNfjIuNX4gZ3JhdmltZXRyaWMgbW9uaXRvcmluZyBkYXRhLioqKiAoVGhlcmUgaXMgYSB2ZXJzaW9uIHRoYXQgZG9lcyB1c2UgdGhlIGdyYXZpbWV0cmljIG1vbml0b3JpbmcgZGF0YSwgYnV0IG5vdCB0aGlzIG9uZSEpIDxicj4gLS0gRGF0YSBmcm9tIHRoZSBFUEEKKip6Y3RhKiogfCBbWmlwIENvZGUgVGFidWxhdGlvbiBBcmVhXShodHRwczovL3d3dzIuY2Vuc3VzLmdvdi9nZW8vcGRmcy9lZHVjYXRpb24vYnJvY2h1cmVzL1pDVEFzLnBkZil7dGFyZ2V0PSJfYmxhbmsifSB3aGVyZSB0aGUgbW9uaXRvciBpcyBsb2NhdGVkIDxicj4gLS0gUG9zdGFsIFppcCBjb2RlcyBhcmUgY29udmVydGVkIGludG8gImdlbmVyYWxpemVkIGFyZWFsIHJlcHJlc2VudGF0aW9ucyIgdGhhdCBhcmUgbm9uLW92ZXJsYXBwaW5nICA8YnI+IC0tIERhdGEgZnJvbSB0aGUgMjAxMCBDZW5zdXMgIAoqKnpjdGFfYXJlYSoqIHwgTGFuZCBhcmVhIG9mIHRoZSB6aXAgY29kZSBhcmVhIGluIG1ldGVycyBzcXVhcmVkICA8YnI+IC0tIERhdGEgZnJvbSB0aGUgMjAxMCBDZW5zdXMgIAoqKnpjdGFfcG9wKiogfCBQb3B1bGF0aW9uIGluIHRoZSB6aXAgY29kZSBhcmVhICA8YnI+IC0tIERhdGEgZnJvbSB0aGUgMjAxMCBDZW5zdXMgIAoqKmltcF9hNTAwKiogfCBJbXBlcnZpb3VzIHN1cmZhY2UgbWVhc3VyZSA8YnI+IC0tIFdpdGhpbiBhIGNpcmNsZSB3aXRoIGEgcmFkaXVzIG9mIDUwMCBtZXRlcnMgYXJvdW5kIHRoZSBtb25pdG9yIDxicj4gLS0gSW1wZXJ2aW91cyBzdXJmYWNlIGFyZSByb2FkcywgY29uY3JldGUsIHBhcmtpbmcgbG90cywgYnVpbGRpbmdzIDxicj4gLS0gVGhpcyBpcyBhIG1lYXN1cmUgb2YgZGV2ZWxvcG1lbnQgCioqaW1wX2ExMDAwKiogfCBJbXBlcnZpb3VzIHN1cmZhY2UgbWVhc3VyZSA8YnI+IC0tICBXaXRoaW4gYSBjaXJjbGUgd2l0aCBhIHJhZGl1cyBvZiAxMDAwIG1ldGVycyBhcm91bmQgdGhlIG1vbml0b3IKKippbXBfYTUwMDAqKiB8IEltcGVydmlvdXMgc3VyZmFjZSBtZWFzdXJlIDxicj4gLS0gIFdpdGhpbiBhIGNpcmNsZSB3aXRoIGEgcmFkaXVzIG9mIDUwMDAgbWV0ZXJzIGFyb3VuZCB0aGUgbW9uaXRvciAgCioqaW1wX2ExMDAwMCoqIHwgSW1wZXJ2aW91cyBzdXJmYWNlIG1lYXN1cmUgPGJyPiAtLSAgV2l0aGluIGEgY2lyY2xlIHdpdGggYSByYWRpdXMgb2YgMTAwMDAgbWV0ZXJzIGFyb3VuZCB0aGUgbW9uaXRvciAgIAoqKmltcF9hMTUwMDAqKiB8IEltcGVydmlvdXMgc3VyZmFjZSBtZWFzdXJlIDxicj4gLS0gIFdpdGhpbiBhIGNpcmNsZSB3aXRoIGEgcmFkaXVzIG9mIDE1MDAwIG1ldGVycyBhcm91bmQgdGhlIG1vbml0b3IgIAoqKmNvdW50eV9hcmVhKiogfCBMYW5kIGFyZWEgb2YgdGhlIGNvdW50eSBvZiB0aGUgbW9uaXRvciBpbiBtZXRlcnMgc3F1YXJlZCAgCioqY291bnR5X3BvcCoqIHwgUG9wdWxhdGlvbiBvZiB0aGUgY291bnR5IG9mIHRoZSBtb25pdG9yICAKKipMb2dfZGlzdF90b19wcmlzZWMqKiB8IExvZyAoTmF0dXJhbCBsb2cpIGRpc3RhbmNlIHRvIGEgcHJpbWFyeSBvciBzZWNvbmRhcnkgcm9hZCBmcm9tIHRoZSBtb25pdG9yIDxicj4gLS0gSGlnaHdheSBvciBtYWpvciByb2FkICAKKipsb2dfcHJpX2xlbmd0aF81MDAwKiogfCBDb3VudCBvZiBwcmltYXJ5IHJvYWQgbGVuZ3RoIGluIG1ldGVycyBpbiBhIGNpcmNsZSB3aXRoIGEgcmFkaXVzIG9mIDUwMDAgbWV0ZXJzIGFyb3VuZCB0aGUgbW9uaXRvciAoTmF0dXJhbCBsb2cpIDxicj4gLS0gSGlnaHdheXMgb25seSAgCioqbG9nX3ByaV9sZW5ndGhfMTAwMDAqKiB8IENvdW50IG9mIHByaW1hcnkgcm9hZCBsZW5ndGggaW4gbWV0ZXJzIGluIGEgY2lyY2xlIHdpdGggYSByYWRpdXMgb2YgMTAwMDAgbWV0ZXJzIGFyb3VuZCB0aGUgbW9uaXRvciAoTmF0dXJhbCBsb2cpIDxicj4gLS0gSGlnaHdheXMgb25seSAgCioqbG9nX3ByaV9sZW5ndGhfMTUwMDAqKiB8IENvdW50IG9mIHByaW1hcnkgcm9hZCBsZW5ndGggaW4gbWV0ZXJzIGluIGEgY2lyY2xlIHdpdGggYSByYWRpdXMgb2YgMTUwMDAgbWV0ZXJzIGFyb3VuZCB0aGUgbW9uaXRvciAoTmF0dXJhbCBsb2cpIDxicj4gLS0gSGlnaHdheXMgb25seSAgCioqbG9nX3ByaV9sZW5ndGhfMjUwMDAqKiB8IENvdW50IG9mIHByaW1hcnkgcm9hZCBsZW5ndGggaW4gbWV0ZXJzIGluIGEgY2lyY2xlIHdpdGggYSByYWRpdXMgb2YgMjUwMDAgbWV0ZXJzIGFyb3VuZCB0aGUgbW9uaXRvciAoTmF0dXJhbCBsb2cpIDxicj4gLS0gSGlnaHdheXMgb25seSAgCioqbG9nX3ByaXNlY19sZW5ndGhfNTAwKiogfCBDb3VudCBvZiBwcmltYXJ5IGFuZCBzZWNvbmRhcnkgcm9hZCBsZW5ndGggaW4gbWV0ZXJzIGluIGEgY2lyY2xlIHdpdGggYSByYWRpdXMgb2YgNTAwIG1ldGVycyBhcm91bmQgdGhlIG1vbml0b3IgKE5hdHVyYWwgbG9nKSAgPGJyPiAtLSBIaWdod2F5IGFuZCBzZWNvbmRhcnkgcm9hZHMgIAoqKmxvZ19wcmlzZWNfbGVuZ3RoXzEwMDAqKiB8IENvdW50IG9mIHByaW1hcnkgYW5kIHNlY29uZGFyeSByb2FkIGxlbmd0aCBpbiBtZXRlcnMgaW4gYSBjaXJjbGUgd2l0aCBhIHJhZGl1cyBvZiAxMDAwIG1ldGVycyBhcm91bmQgdGhlIG1vbml0b3IgKE5hdHVyYWwgbG9nKSAgPGJyPiAtLSBIaWdod2F5IGFuZCBzZWNvbmRhcnkgcm9hZHMgIAoqKmxvZ19wcmlzZWNfbGVuZ3RoXzUwMDAqKiB8IENvdW50IG9mIHByaW1hcnkgYW5kIHNlY29uZGFyeSByb2FkIGxlbmd0aCBpbiBtZXRlcnMgaW4gYSBjaXJjbGUgd2l0aCBhIHJhZGl1cyBvZiA1MDAwIG1ldGVycyBhcm91bmQgdGhlIG1vbml0b3IgKE5hdHVyYWwgbG9nKSAgPGJyPiAtLSBIaWdod2F5IGFuZCBzZWNvbmRhcnkgcm9hZHMgIAoqKmxvZ19wcmlzZWNfbGVuZ3RoXzEwMDAwKiogfCBDb3VudCBvZiBwcmltYXJ5IGFuZCBzZWNvbmRhcnkgcm9hZCBsZW5ndGggaW4gbWV0ZXJzIGluIGEgY2lyY2xlIHdpdGggYSByYWRpdXMgb2YgMTAwMDAgbWV0ZXJzIGFyb3VuZCB0aGUgbW9uaXRvciAoTmF0dXJhbCBsb2cpICA8YnI+IC0tIEhpZ2h3YXkgYW5kIHNlY29uZGFyeSByb2FkcyAgCioqbG9nX3ByaXNlY19sZW5ndGhfMTUwMDAqKiB8IENvdW50IG9mIHByaW1hcnkgYW5kIHNlY29uZGFyeSByb2FkIGxlbmd0aCBpbiBtZXRlcnMgaW4gYSBjaXJjbGUgd2l0aCBhIHJhZGl1cyBvZiAxNTAwMCBtZXRlcnMgYXJvdW5kIHRoZSBtb25pdG9yIChOYXR1cmFsIGxvZykgIDxicj4gLS0gSGlnaHdheSBhbmQgc2Vjb25kYXJ5IHJvYWRzICAKKipsb2dfcHJpc2VjX2xlbmd0aF8yNTAwMCoqIHwgQ291bnQgb2YgcHJpbWFyeSBhbmQgc2Vjb25kYXJ5IHJvYWQgbGVuZ3RoIGluIG1ldGVycyBpbiBhIGNpcmNsZSB3aXRoIGEgcmFkaXVzIG9mIDI1MDAwIG1ldGVycyBhcm91bmQgdGhlIG1vbml0b3IgKE5hdHVyYWwgbG9nKSAgPGJyPiAtLSBIaWdod2F5IGFuZCBzZWNvbmRhcnkgcm9hZHMgICAgICAKKipsb2dfbmVpXzIwMDhfcG0yNV9zdW1fMTAwMDAqKiB8IFRvbnMgb2YgZW1pc3Npb25zIGZyb20gbWFqb3Igc291cmNlcyBkYXRhIGJhc2UgKGFubnVhbCBkYXRhKSBzdW0gb2YgYWxsIHNvdXJjZXMgd2l0aGluIGEgY2lyY2xlIHdpdGggYSByYWRpdXMgb2YgMTAwMDAgbWV0ZXJzIG9mIGRpc3RhbmNlIGFyb3VuZCB0aGUgbW9uaXRvciAoTmF0dXJhbCBsb2cpICAgIAoqKmxvZ19uZWlfMjAwOF9wbTI1X3N1bV8xNTAwMCoqIHwgVG9ucyBvZiBlbWlzc2lvbnMgZnJvbSBtYWpvciBzb3VyY2VzIGRhdGEgYmFzZSAoYW5udWFsIGRhdGEpIHN1bSBvZiBhbGwgc291cmNlcyB3aXRoaW4gYSBjaXJjbGUgd2l0aCBhIHJhZGl1cyBvZiAxNTAwMCBtZXRlcnMgb2YgZGlzdGFuY2UgYXJvdW5kIHRoZSBtb25pdG9yIChOYXR1cmFsIGxvZykgICAgIAoqKmxvZ19uZWlfMjAwOF9wbTI1X3N1bV8yNTAwMCoqIHwgVG9ucyBvZiBlbWlzc2lvbnMgZnJvbSBtYWpvciBzb3VyY2VzIGRhdGEgYmFzZSAoYW5udWFsIGRhdGEpIHN1bSBvZiBhbGwgc291cmNlcyB3aXRoaW4gYSBjaXJjbGUgd2l0aCBhIHJhZGl1cyBvZiAyNTAwMCBtZXRlcnMgb2YgZGlzdGFuY2UgYXJvdW5kIHRoZSBtb25pdG9yIChOYXR1cmFsIGxvZykgICAgIAoqKmxvZ19uZWlfMjAwOF9wbTEwX3N1bV8xMDAwMCoqIHwgVG9ucyBvZiBlbWlzc2lvbnMgZnJvbSBtYWpvciBzb3VyY2VzIGRhdGEgYmFzZSAoYW5udWFsIGRhdGEpIHN1bSBvZiBhbGwgc291cmNlcyB3aXRoaW4gYSBjaXJjbGUgd2l0aCBhIHJhZGl1cyBvZiAxMDAwMCBtZXRlcnMgb2YgZGlzdGFuY2UgYXJvdW5kIHRoZSBtb25pdG9yIChOYXR1cmFsIGxvZykgICAgICAKKipsb2dfbmVpXzIwMDhfcG0xMF9zdW1fMTUwMDAqKnwgVG9ucyBvZiBlbWlzc2lvbnMgZnJvbSBtYWpvciBzb3VyY2VzIGRhdGEgYmFzZSAoYW5udWFsIGRhdGEpIHN1bSBvZiBhbGwgc291cmNlcyB3aXRoaW4gYSBjaXJjbGUgd2l0aCBhIHJhZGl1cyBvZiAxNTAwMCBtZXRlcnMgb2YgZGlzdGFuY2UgYXJvdW5kIHRoZSBtb25pdG9yIChOYXR1cmFsIGxvZykgICAgICAKKipsb2dfbmVpXzIwMDhfcG0xMF9zdW1fMjUwMDAqKiB8IFRvbnMgb2YgZW1pc3Npb25zIGZyb20gbWFqb3Igc291cmNlcyBkYXRhIGJhc2UgKGFubnVhbCBkYXRhKSBzdW0gb2YgYWxsIHNvdXJjZXMgd2l0aGluIGEgY2lyY2xlIHdpdGggYSByYWRpdXMgb2YgMjUwMDAgbWV0ZXJzIG9mIGRpc3RhbmNlIGFyb3VuZCB0aGUgbW9uaXRvciAoTmF0dXJhbCBsb2cpICAgICAgCioqcG9wZGVuc19jb3VudHkqKiB8IFBvcHVsYXRpb24gZGVuc2l0eSAobnVtYmVyIG9mIHBlb3BsZSBwZXIga2lsb21ldGVyIHNxdWFyZWQgYXJlYSBvZiB0aGUgY291bnR5KQoqKnBvcGRlbnNfemN0YSoqIHwgUG9wdWxhdGlvbiBkZW5zaXR5IChudW1iZXIgb2YgcGVvcGxlIHBlciBraWxvbWV0ZXIgc3F1YXJlZCBhcmVhIG9mIHpjdGEpCioqbm9ocyoqIHwgUGVyY2VudGFnZSBvZiBwZW9wbGUgaW4gemN0YSBhcmVhIHdoZXJlIHRoZSBtb25pdG9yIGlzIHRoYXQgKipkbyBub3QgaGF2ZSBhIGhpZ2ggc2Nob29sIGRlZ3JlZSoqIDxicj4gLS0gRGF0YSBmcm9tIHRoZSBDZW5zdXMKKipzb21laHMqKiB8IFBlcmNlbnRhZ2Ugb2YgcGVvcGxlIGluIHpjdGEgYXJlYSB3aGVyZSB0aGUgbW9uaXRvciB3aG9zZSBoaWdoZXN0IGZvcm1hbCBlZHVjYXRpb25hbCBhdHRhaW5tZW50IHdhcyAqKnNvbWUgaGlnaCBzY2hvb2wgZWR1Y2F0aW9uKiogPGJyPiAtLSBEYXRhIGZyb20gdGhlIENlbnN1cwoqKmhzKiogfCBQZXJjZW50YWdlIG9mIHBlb3BsZSBpbiB6Y3RhIGFyZWEgd2hlcmUgdGhlIG1vbml0b3Igd2hvc2UgaGlnaGVzdCBmb3JtYWwgZWR1Y2F0aW9uYWwgYXR0YWlubWVudCB3YXMgY29tcGxldGluZyBhICoqaGlnaCBzY2hvb2wgZGVncmVlKiogPGJyPiAtLSBEYXRhIGZyb20gdGhlIENlbnN1cyAgCioqc29tZWNvbGxlZ2UqKiB8IFBlcmNlbnRhZ2Ugb2YgcGVvcGxlIGluIHpjdGEgYXJlYSB3aGVyZSB0aGUgbW9uaXRvciB3aG9zZSBoaWdoZXN0IGZvcm1hbCBlZHVjYXRpb25hbCBhdHRhaW5tZW50IHdhcyBjb21wbGV0aW5nICoqc29tZSBjb2xsZWdlIGVkdWNhdGlvbioqIDxicj4gLS0gRGF0YSBmcm9tIHRoZSBDZW5zdXMgCioqYXNzb2NpYXRlKiogfCBQZXJjZW50YWdlIG9mIHBlb3BsZSBpbiB6Y3RhIGFyZWEgd2hlcmUgdGhlIG1vbml0b3Igd2hvc2UgaGlnaGVzdCBmb3JtYWwgZWR1Y2F0aW9uYWwgYXR0YWlubWVudCB3YXMgY29tcGxldGluZyBhbiAqKmFzc29jaWF0ZSBkZWdyZWUqKiA8YnI+IC0tIERhdGEgZnJvbSB0aGUgQ2Vuc3VzIAoqKmJhY2hlbG9yKiogfCBQZXJjZW50YWdlIG9mIHBlb3BsZSBpbiB6Y3RhIGFyZWEgd2hlcmUgdGhlIG1vbml0b3Igd2hvc2UgaGlnaGVzdCBmb3JtYWwgZWR1Y2F0aW9uYWwgYXR0YWlubWVudCB3YXMgYSAqKmJhY2hlbG9yJ3MgZGVncmVlKiogPGJyPiAtLSBEYXRhIGZyb20gdGhlIENlbnN1cyAKKipncmFkKiogfCBQZXJjZW50YWdlIG9mIHBlb3BsZSBpbiB6Y3RhIGFyZWEgd2hlcmUgdGhlIG1vbml0b3Igd2hvc2UgaGlnaGVzdCBmb3JtYWwgZWR1Y2F0aW9uYWwgYXR0YWlubWVudCB3YXMgYSAqKmdyYWR1YXRlIGRlZ3JlZSoqIDxicj4gLS0gRGF0YSBmcm9tIHRoZSBDZW5zdXMgCioqcG92KiogfCBQZXJjZW50YWdlIG9mIHBlb3BsZSBpbiB6Y3RhIGFyZWEgd2hlcmUgdGhlIG1vbml0b3IgaXMgdGhhdCBsaXZlZCBpbiBbKipwb3ZlcnR5KipdKGh0dHBzOi8vYXNwZS5oaHMuZ292LzIwMDgtaGhzLXBvdmVydHktZ3VpZGVsaW5lcykgaW4gMjAwOCAtIG9yIHdvdWxkIGl0IGhhdmUgYmVlbiAyMDA3IGd1aWRlbGluZXM/P2h0dHBzOi8vYXNwZS5oaHMuZ292LzIwMDctaGhzLXBvdmVydHktZ3VpZGVsaW5lcyA8YnI+IC0tIERhdGEgZnJvbSB0aGUgQ2Vuc3VzICAKKipoc19vcmxlc3MqKiB8ICBQZXJjZW50YWdlIG9mIHBlb3BsZSBpbiB6Y3RhIGFyZWEgd2hlcmUgdGhlIG1vbml0b3Igd2hvc2UgaGlnaGVzdCBmb3JtYWwgZWR1Y2F0aW9uYWwgYXR0YWlubWVudCB3YXMgYSAqKmhpZ2ggc2Nob29sIGRlZ3JlZSBvciBsZXNzKiogKHN1bSBvZiBub2hzLCBzb21laHMsIGFuZCBocykgIAoqKnVyYzIwMTMqKiB8IFsyMDEzIFVyYmFuLXJ1cmFsIGNsYXNzaWZpY2F0aW9uXShodHRwczovL3d3dy5jZGMuZ292L25jaHMvZGF0YS9zZXJpZXMvc3JfMDIvc3IwMl8xNjYucGRmKXt0YXJnZXQ9Il9ibGFuayJ9IG9mIHRoZSBjb3VudHkgd2hlcmUgdGhlIG1vbml0b3IgaXMgbG9jYXRlZCA8YnI+IC0tIDYgY2F0ZWdvcnkgdmFyaWFibGUgLSAxIGlzIHRvdGFsbHkgdXJiYW4gNiBpcyBjb21wbGV0ZWx5IHJ1cmFsIDxicj4gIC0tIERhdGEgZnJvbSB0aGUgTmF0aW9uYWwgQ2VudGVyIGZvciBIZWFsdGggU3RhdGlzdGljc10oaHR0cHM6Ly93d3cuY2RjLmdvdi9uY2hzL2luZGV4Lmh0bSl7dGFyZ2V0PSJfYmxhbmsifSAgICAgCioqdXJjMjAwNioqIHwgWzIwMDYgVXJiYW4tcnVyYWwgY2xhc3NpZmljYXRpb25dKGh0dHBzOi8vd3d3LmNkYy5nb3YvbmNocy9kYXRhL3Nlcmllcy9zcl8wMi9zcjAyXzE1NC5wZGYpe3RhcmdldD0iX2JsYW5rIn0gb2YgdGhlIGNvdW50eSB3aGVyZSB0aGUgbW9uaXRvciBpcyBsb2NhdGVkIDxicj4gLS0gNiBjYXRlZ29yeSB2YXJpYWJsZSAtIDEgaXMgdG90YWxseSB1cmJhbiA2IGlzIGNvbXBsZXRlbHkgcnVyYWwgPGJyPiAtLSBEYXRhIGZyb20gdGhlIFtOYXRpb25hbCBDZW50ZXIgZm9yIEhlYWx0aCBTdGF0aXN0aWNzXShodHRwczovL3d3dy5jZGMuZ292L25jaHMvaW5kZXguaHRtKXt0YXJnZXQ9Il9ibGFuayJ9ICAgICAKKiphb2QqKiB8IEFlcm9zb2wgT3B0aWNhbCBEZXB0aCBtZWFzdXJlbWVudCBmcm9tIGEgTkFTQSBzYXRlbGxpdGUgPGJyPiAtLSBiYXNlZCBvbiB0aGUgZGlmZnJhY3Rpb24gb2YgYSBsYXNlciA8YnI+IC0tIHVzZWQgYXMgYSBwcm94eSBvZiBwYXJ0aWN1bGF0ZSBwb2xsdXRpb24gPGJyPiAtLSB1bml0LWxlc3MgLSBoaWdoZXIgdmFsdWUgaW5kaWNhdGVzIG1vcmUgcG9sbHV0aW9uIDxicj4gLS0gRGF0YSBmcm9tIE5BU0EgIAoKPC9kZXRhaWxzPgoKTWFueSBvZiB0aGVzZSBmZWF0dXJlcyBoYXZlIHRvIGRvIHdpdGggdGhlIGNpcmN1bGFyIGFyZWEgYXJvdW5kIHRoZSBtb25pdG9yIGNhbGxlZCB0aGUgImJ1ZmZlciIuIFRoZXNlIGFyZSBpbGx1c3RyYXRlZCBpbiB0aGUgZm9sbG93aW5nIGZpZ3VyZToKCmBgYHtyLCBlY2hvID0gRkFMU0UsIG91dC53aWR0aCA9ICI4MDBweCIsfQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbWciLCAicmVncmVzc2lvbi5wbmciKSkKYGBgCgojIyMjIyBbW3NvdXJjZV1dKGh0dHBzOi8vd3d3Lm5jYmkubmxtLm5paC5nb3YvcHVibWVkLzE1MjkyOTA2KXt0YXJnZXQ9Il9ibGFuayJ9CgoKCiMgKipEYXRhIEltcG9ydCoqCioqKgoKQWxsIG9mIG91ciBkYXRhIHdhcyBwcmV2aW91c2x5IGNvbGxlY3RlZCBieSBhIFtyZXNlYXJjaGVyXShodHRwOi8vd3d3LmJpb3N0YXQuamhzcGguZWR1L35ycGVuZy8pIGF0IHRoZSBbSm9obnMgSG9wa2lucyBTY2hvb2wgb2YgUHVibGljIEhlYWx0aF0oaHR0cHM6Ly93d3cuamhzcGguZWR1Lykgd2hvIHN0dWRpZXMgYWlyIHBvbGx1dGlvbiBhbmQgY2xpbWF0ZSBjaGFuZ2UuIAoKV2UgaGF2ZSBvbmUgQ1NWIGZpbGUgdGhhdCBjb250YWlucyBib3RoIG91ciBzaW5nbGUgKipvdXRjb21lIHZhcmlhYmxlKiogYW5kIGFsbCBvZiBvdXIgKipmZWF0dXJlcyoqIChvciBwcmVkaWN0b3IgdmFyaWFibGVzKS4KCk5leHQsIHdlIGltcG9ydCBvdXIgZGF0YSBpbnRvIFIgbm93IHNvIHRoYXQgd2UgY2FuIGV4cGxvcmUgdGhlIGRhdGEgZnVydGhlci4gCldlIHdpbGwgY2FsbCBvdXIgZGF0YSBvYmplY3QgYHBtYCBmb3IgcGFydGljdWxhdGUgbWF0dGVyLiAKV2UgaW1wb3J0IHRoZSBkYXRhIHVzaW5nIHRoZSBgcmVhZF9jc3YoKWAgZnVuY3Rpb24gZnJvbSB0aGUgYHJlYWRyYCBwYWNrYWdlLiAKYGBge3J9CnBtIDwtIHJlYWRyOjpyZWFkX2NzdihoZXJlKCJkb2NzIiwgInBtMjVfZGF0YS5jc3YiKSkKYGBgCgoKCiMgKipEYXRhIEV4cGxvcmF0aW9uIGFuZCBXcmFuZ2xpbmcqKgoqKioKClRoZSBmaXJzdCBzdGVwIGluIHBlcmZvcm1pbmcgYW55IGRhdGEgYW5hbHlzaXMgaXMgdG8gZXhwbG9yZSB0aGUgZGF0YS4gCgpGb3IgZXhhbXBsZSwgd2UgbWlnaHQgd2FudCB0byBiZXR0ZXIgdW5kZXJzdGFuZCB0aGUgdmFyaWFibGVzIGluY2x1ZGVkIGluIHRoZSBkYXRhLCBhcyB3ZSBtYXkgbGVhcm4gYWJvdXQgaW1wb3J0YW50IGRldGFpbHMgYWJvdXQgdGhlIGRhdGEgdGhhdCB3ZSBzaG91bGQga2VlcCBpbiBtaW5kIGFzIHdlIHRyeSB0byBwcmVkaWN0IG91ciBvdXRjb21lIHZhcmlhYmxlLgoKRmlyc3QsIGxldCdzIGp1c3QgZ2V0IGEgZ2VuZXJhbCBzZW5zZSBvZiBvdXIgZGF0YS4gCldlIGNhbiBkbyB0aGF0IHVzaW5nIHRoZSBgZ2xpbXBzZSgpYCBmdW5jdGlvbiBvZiB0aGUgYGRwbHlyYCBwYWNrYWdlIChpdCBpcyBhbHNvIGluIHRoZSBgdGliYmxlYCBwYWNrYWdlKS4KCldlIHdpbGwgYWxzbyB1c2UgdGhlIGAlPiVgIHBpcGUsIHdoaWNoIGNhbiBiZSB1c2VkIHRvIGRlZmluZSB0aGUgaW5wdXQgZm9yIGxhdGVyIHNlcXVlbnRpYWwgc3RlcHMuIAoKVGhpcyB3aWxsIG1ha2UgbW9yZSBzZW5zZSB3aGVuIHdlIGhhdmUgbXVsdGlwbGUgc2VxdWVudGlhbCBzdGVwcyB1c2luZyB0aGUgc2FtZSBkYXRhIG9iamVjdC4gCgpUbyB1c2UgdGhlIHBpcGUgbm90YXRpb24gd2UgbmVlZCB0byBpbnN0YWxsIGFuZCBsb2FkIGBkcGx5cmAgYXMgd2VsbC4KCkZvciBleGFtcGxlLCBoZXJlIHdlIHN0YXJ0IHdpdGggYHBtYCBkYXRhIG9iamVjdCBhbmQgInBpcGUiIHRoZSBvYmplY3QgaW50byBhcyBpbnB1dCBpbnRvIHRoZSBgZ2xpbXBzZSgpYCBmdW5jdGlvbi4gClRoZSBvdXRwdXQgaXMgaXMgYW4gb3ZlcnZpZXcgb2Ygd2hhdCBpcyBpbiB0aGUgYHBtYCBvYmplY3Qgc3VjaCBhcyB0aGUgbnVtYmVyIG9mIHJvd3MgYW5kIGNvbHVtbnMsIGFsbCB0aGUgY29sdW1uIG5hbWVzLCB0aGUgZGF0YSB0eXBlcyBmb3IgZWFjaCBjb2x1bW4gYW5kIHRoZSBmaXJzdCB2aWV3IHZhbHVlcyBpbiBlYWNoIGNvbHVtbi4gClRoZSBvdXRwdXQgYmVsb3cgaXMgc2Nyb2xsYWJsZSBzbyB5b3UgY2FuIHNlZSBldmVyeXRoaW5nIGZyb20gdGhlIGBnbGltcHNlKClgIGZ1bmN0aW9uLiAKCiMjIyMgey5zY3JvbGxhYmxlIH0KCmBgYHtyfQojIFNjcm9sbCB0aHJvdWdoIHRoZSBvdXRwdXQhCnBtICU+JQogIGRwbHlyOjpnbGltcHNlKCkKYGBgCgojIyMjCgpXZSBjYW4gc2VlIHRoYXQgdGhlcmUgYXJlIDg3NiBtb25pdG9ycyAocm93cykgYW5kIHRoYXQgd2UgaGF2ZSA1MCB0b3RhbCB2YXJpYWJsZXMgKGNvbHVtbnMpIC0gb25lIG9mIHdoaWNoIGlzIHRoZSBvdXRjb21lIHZhcmlhYmxlLiBJbiB0aGlzIGNhc2UsIHRoZSBvdXRjb21lIHZhcmlhYmxlIGlzIGNhbGxlZCBgdmFsdWVgLiAKCkFWT0NBRE86IFNob3VsZCB3ZSBsaW5rIHRvIGEgY29kZSBib29rIGhlcmU/IExpa2UgY291bGQgd2UgdXNlIHRoaXMgYXMgYSB0ZWFjaGluZyBvcHBvcnR1bml0eSB0byBkZW1vbnN0cmF0ZSB0aGUgcHVycG9zZSBvZiBhIGNvZGUgYm9vayBzbyBhIHN0dWRlbnQga25vd3MgaG93IHdlIGtub3cgdGhlIFBNIHZhbHVlcyBhcmUgYHZhbHVlYD8KCmF2b2NhZG8gcmVzcG9uc2U6IHRoZXJlIGlzbnQgYSBjb2RlIGJvb2sgcmVsYXRlZCB0byB0aGlzIGRhdGEsIFJvZ2VyIHdyYW5nbGVkIGl0IGZvciBtZSwgYnV0IHRoZSB2YXBpbmcgY2FzZSBzdHVkeSBhY3R1YWxseSB1c2VzIGNvZGUgYm9va3MgZm9yIHRoYXQgZGF0YS4gV291bGQgeW91IGxpa2UgdG8gbGluayB0byBhIGdlbmVyaWMgY29kZSBib29rIGFuZCBkZXNjcmliZSB0aGF0IHByb2Nlc3M/IEkgZGlkIGhvd2V2ZXIgYWRkIGluZm9ybWF0aW9uIGFib3V0IFJvZ2VyIGFuZCBob3cgaGUgcHJldmlvdXNseSBjb2xsZWN0ZWQgdGhlIGRhdGEuCgpOb3RpY2UgdGhhdCBzb21lIG9mIHRoZSB2YXJpYWJsZXMgdGhhdCB3ZSB3b3VsZCB0aGluayBvZiBhcyBmYWN0b3JzIChvciBjYXRlZ29yaWNhbCBkYXRhKSBhcmUgY3VycmVudGx5IG9mIGNsYXNzIGNoYXJhY3RlciBhcyBpbmRpY2F0ZWQgYnkgdGhlIGA8Y2hyPmAganVzdCB0byB0aGUgcmlnaHQgb2YgdGhlIGNvbHVtbiBuYW1lcy92YXJpYWJsZSBuYW1lcyBpbiB0aGUgYGdsaW1wc2UoKWAgb3V0cHV0LiBUaGlzIG1lYW5zIHRoYXQgdGhlIHZhcmlhYmxlIHZhbHVlcyBhcmUgY2hhcmFjdGVyIHN0cmluZ3MsIHN1Y2ggYXMgd29yZHMgb3IgcGhyYXNlcy4gCgpUaGUgb3RoZXIgdmFyaWFibGVzIGFyZSBvZiBjbGFzcyBgPGRibD5gLCB3aGljaCBzdGFuZHMgZm9yIGRvdWJsZSBwcmVjaXNpb24gd2hpY2ggaW5kaWNhdGVzIHRoYXQgdGhlIGFyZSBudW1lcmljIGFuZCB0aGF0IHRoZXkgaGF2ZSBkZWNpbWFsIHZhbHVlcy4gSW4gY29udHJhc3QsIG9uZSBjb3VsZCBoYXZlIGludGVnZXIgdmFsdWVzIHdoaWNoIHdvdWxkIG5vdCBhbGxvdyBmb3IgZGVjaW1hbCBudW1iZXJzLiBIZXJlIGlzIGEgW2xpbmtdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0RvdWJsZS1wcmVjaXNpb25fZmxvYXRpbmctcG9pbnRfZm9ybWF0KXt0YXJnZXQ9Il9ibGFuayJ9IGZvciBtb3JlIGluZm9ybWF0aW9uIG9uIGRvdWJsZSBwcmVjaXNpb24gbnVtZXJpYyB2YWx1ZXMuCgpBbm90aGVyIGNvbW1vbiBkYXRhIGNsYXNzIGlzIGZhY3RvciB3aGljaCBpcyBhYmJyZXZpYXRlZCBsaWtlIHRoaXM6IGA8ZmN0PmAuIEEgZmFjdG9yIGlzIHNvbWV0aGluZyB0aGF0IGhhcyB1bmlxdWUgbGV2ZWxzIGJ1dCB0aGVyZSBpcyBubyBhcHByZWNpYWJsZSBvcmRlciB0byB0aGUgbGV2ZWxzLiBGb3IgZXhhbXBsZSB3ZSBjYW4gaGF2ZSBhIG51bWVyaWMgdmFsdWUgdGhhdCBpcyBqdXN0IGFuIGlkIHRoYXQgd2Ugd2FudCB0byBiZSBpbnRlcnByZXRlZCBhcyBqdXN0IGEgdW5pcXVlIGxldmVsIGFuZCBub3QgYXMgdGhlIG51bWJlciB0aGF0IGl0IHdvdWxkIHR5cGljYWxseSBpbmRpY2F0ZS4gVGhpcyB3b3VsZCBiZSB1c2VmdWwgZm9yIHNldmVyYWwgb2Ygb3VyIHZhcmlhYmxlczoKCjEuIHRoZSBtb25pdG9yIElEIChgaWRgKQoyLiB0aGUgRmVkZXJhbCBJbmZvcm1hdGlvbiBQcm9jZXNzaW5nIFN0YW5kYXJkIG51bWJlciBmb3IgdGhlIGNvdW50eSB3aGVyZSB0aGUgbW9uaXRvciB3YXMgbG9jYXRlZCAoYGZpcHNgKQozLiB0aGUgemlwIGNvZGUgdGFidWxhdGlvbiBhcmVhIChgemN0YWApCgpOb25lIG9mIHRoZSB2YWx1ZXMgYWN0dWFsbHkgaGF2ZSBhbnkgcmVhbCBudW1lcmljIG1lYW5pbmcsIHNvIHdlIHdhbnQgdG8gbWFrZSBzdXJlIHRoYXQgUiBkb2VzIG5vdCBpbnRlcnByZXQgdGhlbSBhcyBpZiB0aGV5IGRvLiAKClNvIGxldCdzIGNvbnZlcnQgdGhlc2UgdmFyaWFibGVzIGludG8gZmFjdG9ycy4gCldlIGNhbiBkbyB0aGlzIHVzaW5nIHRoZSBgYWNyb3NzKClgIGZ1bmN0aW9uIG9mIHRoZSBgZHBseXJgIHBhY2thZ2UgYW5kIHRoZSBgYXMuZmFjdG9yKClgIGJhc2UgZnVuY3Rpb24uIApUaGUgYGFjcm9zcygpYCBmdW5jdGlvbiBoYXMgdHdvIG1haW4gYXJndW1lbnRzOiAoaSkgdGhlIGNvbHVtbnMgeW91IHdhbnQgdG8gb3BlcmF0ZSBvbiBhbmQgKGlpKSB0aGUgZnVuY3Rpb24gb3IgbGlzdCBvZiBmdW5jdGlvbnMgdG8gYXBwbHkgdG8gZWFjaCBjb2x1bW4uIAoKSW4gdGhpcyBjYXNlLCB3ZSBhcmUgYWxzbyB1c2luZyB0aGUgYG1hZ3JpdHRyYCBhc3NpZ25tZW50IHBpcGUgb3IgZG91YmxlIHBpcGUgdGhhdCBsb29rcyBsaWtlIHRoaXMgYCU8PiVgIG9mIHRoZSBgbWFncml0dHJgIHBhY2thZ2UuIApUaGlzIGFsbG93cyB1cyB1c2UgdGhlIGBwbWAgZGF0YSBhcyBpbnB1dCwgYnV0IGFsc28gcmVhc3NpZ25zIHRoZSBvdXRwdXQgdG8gdGhlIHNhbWUgZGF0YSBvYmplY3QgbmFtZS4KCiMjIyMgey5zY3JvbGxhYmxlIH0KCmBgYHtyfQojIFNjcm9sbCB0aHJvdWdoIHRoZSBvdXRwdXQhCnBtICU8PiUKICBtdXRhdGUoYWNyb3NzKGMoaWQsIGZpcHMsIHpjdGEpLCBhcy5mYWN0b3IpKSAKCmdsaW1wc2UocG0pCmBgYAoKIyMjIwoKR3JlYXQhIE5vdyB3ZSBjYW4gc2VlIHRoYXQgdGhlc2UgdmFyaWFibGVzIGFyZSBub3cgZmFjdG9ycyBhcyBpbmRpY2F0ZWQgYnkgYDxmY3Q+YCBhZnRlciB0aGUgdmFyaWFibGUgbmFtZS4KCiMjIyBTa2ltIHBhY2thZ2UKClRoZSBgc2tpbSgpYCBmdW5jdGlvbiBvZiB0aGUgYHNraW1yYCBwYWNrYWdlIGlzIGFsc28gcmVhbGx5IGhlbHBmdWwgZm9yIGdldHRpbmcgYSBnZW5lcmFsIHNlbnNlIG9mIHlvdXIgZGF0YS4KQnkgZGVzaWduLCBpdCBwcm92aWRlcyBzdW1tYXJ5IHN0YXRpc3RpY3MgYWJvdXQgdmFyaWFibGVzIGluIHRoZSBkYXRhIHNldC4gCgoKIyMjIyB7LnNjcm9sbGFibGUgfQoKYGBge3J9CiMgU2Nyb2xsIHRocm91Z2ggdGhlIG91dHB1dCEKc2tpbShwbSkKYGBgCgojIyMjCgpOb3RpY2UgaG93IHRoZXJlIGlzIGEgY29sdW1uIGNhbGxlZCBgbl9taXNzaW5nYCBhYm91dCB0aGUgbnVtYmVyIG9mIHZhbHVlcyB0aGF0IGFyZSBtaXNzaW5nLiAKClRoaXMgaXMgYWxzbyBpbmRpY2F0ZWQgYnkgdGhlIGBjb21wbGV0ZV9yYXRlYCB2YXJpYWJsZSAob3IgbWlzc2luZy9udW1iZXIgb2Ygb2JzZXJ2YXRpb25zKS4gCgpJbiBvdXIgZGF0YSBzZXQsIGl0IGxvb2tzIGxpa2Ugb3VyIGRhdGEgZG8gbm90IGNvbnRhaW4gYW55IG1pc3NpbmcgZGF0YS4gCgpBbHNvIG5vdGljZSBob3cgdGhlIGZ1bmN0aW9uIHByb3ZpZGVzIHNlcGFyYXRlIHRhYmxlcyBvZiBzdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIGVhY2ggZGF0YSB0eXBlOiBjaGFyYWN0ZXIsIGZhY3RvciBhbmQgbnVtZXJpYy4gCgpOZXh0LCB0aGUgYG5fdW5xaXVlYCBjb2x1bW4gc2hvd3MgdXMgdGhlIG51bWJlciBvZiB1bmlxdWUgdmFsdWVzIGZvciBlYWNoIG9mIG91ciBjb2x1bW5zLiAKV2UgY2FuIHNlZSB0aGF0IHRoZXJlIGFyZSA0OSBzdGF0ZXMgcmVwcmVzZW50ZWQgaW4gdGhlIGRhdGEuCgpXZSBjYW4gc2VlIHRoYXQgZm9yIG1hbnkgdmFyaWFibGVzIHRoZXJlIGFyZSBtYW55IGxvdyB2YWx1ZXMgYXMgdGhlIGRpc3RyaWJ1dGlvbiBzaG93cyB0d28gcGVha3MsIG9uZSBuZWFyIHplcm8gYW5kIGFub3RoZXIgd2l0aCBhIGhpZ2hlciB2YWx1ZS4gCgpUaGlzIGlzIHRydWUgZm9yIHRoZSBgaW1wYCB2YXJpYWJsZXMgKG1lYXN1cmVzIG9mIGRldmVsb3BtZW50KSwgdGhlIGBuZWlgIHZhcmlhYmxlcyAobWVhc3VyZXMgb2YgZW1pc3Npb24gc291cmNlcykgYW5kIHRoZSByb2FkIGRlbnNpdHkgdmFyaWFibGVzLiAKCldlIGNhbiBhbHNvIHNlZSB0aGF0IHRoZSByYW5nZSBvZiBzb21lIG9mIHRoZSB2YXJpYWJsZXMgaXMgdmVyeSBsYXJnZSwgaW4gcGFydGljdWxhciB0aGUgYXJlYSBhbmQgcG9wdWxhdGlvbiByZWxhdGVkIHZhcmlhYmxlcy4KCgpMZXQncyB0YWtlIGEgbG9vayB0byBzZWUgd2hpY2ggc3RhdGVzIGFyZSBpbmNsdWRlZCB1c2luZyB0aGUgYGRpc3RpbmN0KClgIGZ1bmN0aW9uIG9mIHRoZSBgZHBseXJgIHBhY2thZ2U6CgpgYGB7ciwgZXZhbCA9IEZBTFNFfSAKcG0gJT4lIAogIGRpc3RpbmN0KHN0YXRlKSAKYGBgCgoKU2Nyb2xsIHRocm91Z2ggdGhlIG91dHB1dDoKCiMjIyMgey5zY3JvbGxhYmxlIH0KYGBge3IsIGVjaG8gPSBGQUxTRX0KIyBTY3JvbGwgdGhyb3VnaCB0aGUgb3V0cHV0IQpwbSAlPiUgCiAgZGlzdGluY3Qoc3RhdGUpICU+JQojIHRoaXMgYWxsb3dzIHVzIHRvIHNob3cgdGhlIGZ1bGwgb3V0cHV0IGluIHRoZSByZW5kZXJlZCBybWFya2Rvd24KIHByaW50KG4gPSAxZTMpCmBgYAojIyMjCgpJdCBsb29rcyBsaWtlICJEaXN0cmljdCBvZiBDb2x1bWJpYSIgaXMgYmVpbmcgaW5jbHVkZWQgYXMgYSBzdGF0ZS4gCldlIGNhbiBzZWUgdGhhdCBBbGFza2EgYW5kIEhhd2FpaSBhcmUgbm90IGluY2x1ZGVkIGluIHRoZSBkYXRhLgoKCiMjIEV2YWx1YXRlIGNvcnJlbGF0aW9uCgpJbiBwcmVkaWN0aW9uIGFuYWx5c2VzLCBpdCBpcyBhbHNvIHVzZWZ1bCB0byBldmFsdWF0ZSBpZiBhbnkgb2YgdGhlIHZhcmlhYmxlcyBhcmUgY29ycmVsYXRlZC4gV2h5IHNob3VsZCB3ZSBjYXJlIGFib3V0IHRoaXM/CgpJZiB3ZSBhcmUgdXNpbmcgYSBsaW5lYXIgcmVncmVzc2lvbiB0byBtb2RlbCBvdXIgZGF0YSB0aGVuIHdlIG1pZ2h0IHJ1biBpbnRvIGEgcHJvYmxlbSBjYWxsZWQgbXVsdGljb2xpbmVhcml0eSB3aGljaCBjYW4gbGVhZCB1cyB0byBtaXNpbnRlcnByZXQgd2hhdCBpcyByZWFsbHkgcHJlZGljdGl2ZSBvZiBvdXIgb3V0Y29tZSB2YXJpYWJsZS4gVGhpcyBwaGVub21lbm9uIG9jY3VycyB3aGVuIHRoZSBwcmVkaWN0b3IgdmFyaWFibGVzIGFjdHVhbGx5IHByZWRpY3Qgb25lIGFub3RoZXIuIFNlZSBbdGhpcyBjYXNlIHN0dWR5XShodHRwczovL29wZW5jYXNlc3R1ZGllcy5naXRodWIuaW8vb2NzLWJwLVJUQy1hbmFseXNpcy8pIGZvciBhIGRlZXBlciBleHBsYW5hdGlvbiBhYm91dCB0aGlzLiAKCkFub3RoZXIgcmVhc29uIHdlIHNob3VsZCBsb29rIG91dCBmb3IgY29ycmVsYXRpb24gaXMgdGhhdCB3ZSBkb24ndCB3YW50IHRvIGluY2x1ZGUgcmVkdW5kYW50IHZhcmlhYmxlcy4gVGhpcyBjYW4gYWRkIHVubmVjZXNzYXJ5IG5vaXNlIHRvIG91ciBhbGdvcml0aG0gY2F1c2luZyBhIHJlZHVjdGlvbiBpbiBwcmVkaWN0aW9uIGFjY3VyYWN5IGFuZCBpdCBjYW4gY2F1c2Ugb3VyIGFsZ29yaXRobSB0byBiZSB1bm5lY2Vzc2FyaWx5IHNsb3dlci4gRmluYWxseSwgaXQgY2FuIGFsc28gbWFrZSBpdCBkaWZmaWN1bHQgdG8gaW50ZXJwcmV0IHdoYXQgdmFyaWFibGVzIGFyZSBhY3R1YWxseSBwcmVkaWN0aXZlLgoKSW50dWl0aXZlbHkgd2UgY2FuIGV4cGVjdCBzb21lIG9mIG91ciB2YXJpYWJsZXMgdG8gYmUgY29ycmVsYXRlZC4KCkxldCdzIGZpcnN0IHRha2UgYSBsb29rIGF0IGFsbCBvZiBvdXIgbnVtZXJpYyB2YXJpYWJsZXMgd2l0aCB0aGVgY29ycnBsb3RgIHBhY2thZ2U6ClRoZSBgY29ycnBsb3RgIHBhY2thZ2UgaXMgYW5vdGhlciBvcHRpb24gdG8gbG9vayBhdCBjb3JyZWxhdGlvbiBhbW9uZyBwb3NzaWJsZSBwcmVkaWN0b3JzLCBhbmQgcGFydGljdWxhcmx5IHVzZWZ1bCBpZiB3ZSBoYXZlIG1hbnkgcHJlZGljdG9ycy4gCgpGaXJzdCwgd2UgY2FsY3VsYXRlIHRoZSBQZWFyc29uIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50cyBiZXR3ZWVuIGFsbCBmZWF0dXJlcyBwYWlyd2lzZSB1c2luZyB0aGUgYGNvcigpYCBmdW5jdGlvbiBvZiB0aGUgYHN0YXRzYCBwYWNrYWdlICh3aGljaCBpcyBsb2FkZWQgYXV0b21hdGljYWxseSkuIFRoZW4gd2UgdXNlIHRoZSBgY29ycnBsb3Q6OmNvcnJwbG90KClgIGZ1bmN0aW9uLiAKCmBgYHtyfQpQTV9jb3IgPC0gY29yKHBtICU+JSBkcGx5cjo6c2VsZWN0X2lmKGlzLm51bWVyaWMpKQpjb3JycGxvdDo6Y29ycnBsb3QoUE1fY29yLCB0bC5jZXggPSAwLjUpCmBgYApUaGUgYHRsLmNleCA9IDAuNWAgYXJndW1lbnQgY29udHJvbHMgdGhlIHNpemUgb2YgdGhlIHRleHQgbGFiZWwuIAoKV2UgY2FuIGFsc28gcGxvdCB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhlIFBlYXJzb24gY29ycmVsYXRpb24gY29lZmZpY2llbnRzIHVzaW5nIHRoZSBgYWJzKClgIGZ1bmN0aW9uIGZyb20gYmFzZSBSIGFuZCBjaGFuZ2UgdGhlIG9yZGVyIG9mIHRoZSBjb2x1bW5zLiAgCmBgYHtyfQpjb3JycGxvdChhYnMoUE1fY29yKSwgb3JkZXIgPSAiaGNsdXN0IiwgdGwuY2V4ID0gMC41LCBjbC5saW0gPSBjKDAsIDEpKQoKYGBgCgpUaGVyZSBhcmUgc2V2ZXJhbCBvcHRpb25zIGZvciBvcmRlcmluZyB0aGUgdmFyaWFibGVzLiBTZWUgW2hlcmVdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9jb3JycGxvdC92aWduZXR0ZXMvY29ycnBsb3QtaW50cm8uaHRtbCkgZm9yIG1vcmUgb3B0aW9ucy4gSGVyZSB3ZSB3aWxsIHVzZSB0aGUgImhjbHVzdCIgb3B0aW9uIGZvciBvcmRlcmluZyBieSBbaGllcmFyY2hpY2FsIGNsdXN0ZXJpbmddKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0hpZXJhcmNoaWNhbF9jbHVzdGVyaW5nKSAtIHdoaWNoIHdpbGwgb3JkZXIgdGhlIHZhcmlhYmxlcyBieSBob3cgc2ltaWxhciB0aGV5IGFyZSB0byBvbmUgYW5vdGhlci4KClRoZSBgY2wubGltID0gYygwLCAxKWAgYXJndW1lbnQgbGltaXRzIHRoZSBjb2xvciBsYWJlbCB0byBiZSBiZXR3ZWVuIDAgYW5kIDEuIAoKCldlIGNhbiBzZWUgdGhhdCB0aGUgZGV2ZWxvcG1lbnQgdmFyaWFibGVzIChgaW1wYCkgdmFyaWFibGVzIGFyZSBjb3JyZWxhdGVkIHdpdGggZWFjaCBvdGhlciBhcyB3ZSBtaWdodCBleHBlY3QuIApXZSBhbHNvIHNlZSB0aGF0IHRoZSByb2FkIGRlbnNpdHkgdmFyaWFibGVzIHNlZW0gdG8gYmUgY29ycmVsYXRlZCB3aXRoIGVhY2ggb3RoZXIsIGFuZCB0aGUgZW1pc3Npb24gdmFyaWFibGVzIHNlZW0gdG8gYmUgY29ycmVsYXRlZCB3aXRoIGVhY2ggb3RoZXIuIAoKCkFsc28gbm90aWNlIHRoYXQgbm9uZSBvZiB0aGUgcHJlZGljdG9ycyBhcmUgaGlnaGx5IGNvcnJlbGF0ZWQgd2l0aCBvdXIgb3V0Y29tZSB2YXJpYWJsZSAoYHZhbHVlYCkuCgpXZSBjYW4gdGFrZSBhbHNvIHRha2UgYSBjbG9zZXIgbG9vayAgdXNpbmcgdGhlIGBnZ2NvcnIoKWAgZnVuY3Rpb24gYW5kIHRoZSBgZ2dwYWlycygpYCBmdW5jdGlvbiBvZiB0aGUgYEdHYWxseWAgcGFja2FnZS4gCgpUbyBzZWxlY3Qgb3VyIHZhcmlhYmxlcyBvZiBpbnRlcmVzdCB3ZSBjYW4gdXNlIHRoZSBgc2VsZWN0KClgIGZ1bmN0aW9uIHdpdGggdGhlIGBjb250YWlucygpYCBmdW5jdGlvbiBvZiB0aGUgYHRpZHlyYCBwYWNrYWdlLiAKCkZpcnN0IGxldCdzIGxvb2sgYXQgdGhlIGBpbXBgL2RldmVsb3BtZW50IHZhcmlhYmxlcy4gCldlIGNhbiBjaGFuZ2UgdGhlIGRlZmF1bHQgY29sb3IgcGFsZXR0ZSAoYHBhbGV0dGUgPSAiUmRCdSJgKSBhbmQgYWRkIG9uIApjb3JyZWxhdGlvbiBjb2VmZmljaWVudHMgdG8gdGhlIHBsb3QgKGBsYWJlbCA9IFRSVUVgKS4KCmBgYHtyLCBvdXQud2lkdGggPSAiNDAwcHgifQpzZWxlY3QocG0sIGNvbnRhaW5zKCJpbXAiKSkgJT4lCiAgZ2djb3JyKHBhbGV0dGUgPSAiUmRCdSIsIGxhYmVsID0gVFJVRSkKCnNlbGVjdChwbSwgY29udGFpbnMoImltcCIpKSAlPiUKICBnZ3BhaXJzKCkKYGBgCgoKCkluZGVlZCwgd2UgY2FuIHNlZSB0aGF0IGBpbXBfYTEwMDBgIGFuZCBgaW1wX2E1MDBgIGFyZSBoaWdobHkgY29ycmVsYXRlZCwgYXMgd2VsbCBhcyBgaW1wX2ExMDAwMGAsIGBpbXBfYTE1MDAwYC4KCk5leHQsIGxldCdzIHRha2UgYSBsb29rIGF0IHRoZSByb2FkIGRlbnNpdHkgZGF0YToKCmBgYHtyLCBmaWcud2VpZ2h0PTEyfQpzZWxlY3QocG0sIGNvbnRhaW5zKCJwcmkiKSkgJT4lCiAgZ2djb3JyKHBhbGV0dGUgPSAiUmRCdSIsIGhqdXN0ID0gLjg1LCBzaXplID0gMywKICAgICAgIGxheW91dC5leHA9MiwgbGFiZWwgPSBUUlVFKQpgYGAKCldlIGNhbiBzZWUgdGhhdCBtYW55IG9mIHRoZSByb2FkIGRlbnNpdHkgdmFyaWFibGVzIGFyZSBoaWdobHkgY29ycmVsYXRlZCB3aXRoIG9uZSBhbm90aGVyLCB3aGlsZSBvdGhlcnMgYXJlIGxlc3Mgc28uCgpGaW5hbGx5IGxldCdzIGxvb2sgYXQgdGhlIGVtaXNzaW9uIHZhcmlhYmxlcy4KCmBgYHtyfQpzZWxlY3QocG0sIGNvbnRhaW5zKCJuZWkiKSkgJT4lCiAgZ2djb3JyKHBhbGV0dGUgPSAiUmRCdSIsIGhqdXN0ID0gLjg1LCBzaXplID0gMywKICAgICAgIGxheW91dC5leHA9MiwgbGFiZWwgPSBUUlVFKQoKc2VsZWN0KHBtLCBjb250YWlucygibmVpIikpICU+JQogIGdncGFpcnMoKQpgYGAKCldlIHdvdWxkIGFsc28gZXhwZWN0IHRoZSBwb3B1bGF0aW9uIGRlbnNpdHkgZGF0YSBtaWdodCBjb3JyZWxhdGUgd2l0aCBzb21lIG9mIHRoZXNlIHZhcmlhYmxlcy4gCkxldCdzIHRha2UgYSBsb29rLgoKYGBge3J9CnBtICU+JQpzZWxlY3QobG9nX25laV8yMDA4X3BtMjVfc3VtXzEwMDAwLCBwb3BkZW5zX2NvdW50eSwgCiAgICAgICBsb2dfcHJpX2xlbmd0aF8xMDAwMCwgaW1wX2ExMDAwMCkgJT4lCiAgZ2djb3JyKHBhbGV0dGUgPSAiUmRCdSIsICBoanVzdCA9IC44NSwgc2l6ZSA9IDMsCiAgICAgICBsYXlvdXQuZXhwPTIsIGxhYmVsID0gVFJVRSkKCnBtICU+JQpzZWxlY3QobG9nX25laV8yMDA4X3BtMjVfc3VtXzEwMDAwLCBwb3BkZW5zX2NvdW50eSwgCiAgICAgICBsb2dfcHJpX2xlbmd0aF8xMDAwMCwgaW1wX2ExMDAwMCwgY291bnR5X3BvcCkgJT4lCiAgZ2dwYWlycygpCmBgYAoKCkludGVyZXN0aW5nLCBzbyB0aGVzZSB2YXJpYWJsZXMgZG9uJ3QgYXBwZWFyIHRvIGJlIGhpZ2hseSBjb3JyZWxhdGVkLCB0aGVyZWZvcmUgd2UgbWlnaHQgbmVlZCB2YXJpYWJsZXMgZnJvbSBlYWNoIG9mIHRoZSBjYXRlZ29yaWVzIHRvIHByZWRpY3Qgb3VyIG1vbml0b3IgUE1+Mi41fiBwb2xsdXRpb24gdmFsdWVzLgoKQmVjYXVzZSBzb21lIHZhcmlhYmxlcyBpbiBvdXIgZGF0YSBoYXZlIGV4dHJlbWUgdmFsdWVzLCBpdCBtaWdodCBiZSBnb29kIHRvIHRha2UgYSBsb2cgdHJhbnNmb3JtYXRpb24uIFRoaXMgY2FuIGFmZmVjdCBvdXIgZXN0aW1hdGVzIG9mIGNvcnJlbGF0aW9uLiAKYGBge3J9CnBtICU+JQogIG11dGF0ZShsb2dfcG9wZGVuc19jb3VudHk9IGxvZyhwb3BkZW5zX2NvdW50eSkpICU+JQpzZWxlY3QobG9nX25laV8yMDA4X3BtMjVfc3VtXzEwMDAwLCBsb2dfcG9wZGVuc19jb3VudHksIAogICAgICAgbG9nX3ByaV9sZW5ndGhfMTAwMDAsIGltcF9hMTAwMDApICU+JQogIGdnY29ycihwYWxldHRlID0gIlJkQnUiLCAgaGp1c3QgPSAuODUsIHNpemUgPSAzLAogICAgICAgbGF5b3V0LmV4cD0yLCBsYWJlbCA9IFRSVUUpCgpwbSAlPiUKICBtdXRhdGUobG9nX3BvcGRlbnNfY291bnR5PSBsb2cocG9wZGVuc19jb3VudHkpKSAlPiUKICBtdXRhdGUobG9nX3BvcF9jb3VudHkgPSBsb2coY291bnR5X3BvcCkpICU+JQpzZWxlY3QobG9nX25laV8yMDA4X3BtMjVfc3VtXzEwMDAwLCBsb2dfcG9wZGVuc19jb3VudHksIAogICAgICAgbG9nX3ByaV9sZW5ndGhfMTAwMDAsIGltcF9hMTAwMDAsIGxvZ19wb3BfY291bnR5KSAlPiUKICBnZ3BhaXJzKCkKYGBgCgpJbmRlZWQgdGhpcyBpbmNyZWFzZWQgdGhlIGNvcnJlbGF0aW9uLCBidXQgdmFyaWFibGVzIGZyb20gZWFjaCBvZiB0aGVzZSBjYXRlZ29yaWVzIG1heSBzdGlsbCBwcm92ZSB0byBiZSB1c2VmdWwgZm9yIHByZWRpY3Rpb24uCgpOb3cgdGhhdCB3ZSBoYXZlIGEgc2Vuc2Ugb2Ygd2hhdCBvdXIgZGF0YSBhcmUsIHdlIGNhbiBnZXQgc3RhcnRlZCB3aXRoIGJ1aWxkaW5nIGEgbWFjaGluZSBsZWFybmluZyBtb2RlbCB0byBwcmVkaWN0IGFpciBwb2xsdXRpb24uIAoKIyAqKldoYXQgaXMgbWFjaGluZSBsZWFybmluZz8qKiAgeyN3aGF0aXNtbH0KKioqCgpZb3UgbWF5IGhhdmUgbGVhcm5lZCBhYm91dCB0aGUgY2VudHJhbCBkb2dtYSBvZiBzdGF0aXN0aWNzIHRoYXQgeW91IHNhbXBsZSBmcm9tIGEgcG9wdWxhdGlvbi4KCiFbXShpbWcvY2RpMS5wbmcpCgpUaGVuIHlvdSB1c2UgdGhlIHNhbXBsZSB0byB0cnkgdG8gZ3Vlc3Mgd2hhdCBpcyBoYXBwZW5pbmcgaW4gdGhlIHBvcHVsYXRpb24uCgohW10oaW1nL2NkaTIucG5nKQoKRm9yIHByZWRpY3Rpb24gd2UgaGF2ZSBhIHNpbWlsYXIgc2FtcGxpbmcgcHJvYmxlbQoKIVtdKGltZy9jZHAxLnBuZykKCkJ1dCBub3cgd2UgYXJlIHRyeWluZyB0byBidWlsZCBhIHJ1bGUgdGhhdCBjYW4gYmUgdXNlZCB0byBwcmVkaWN0IGEgc2luZ2xlIG9ic2VydmF0aW9uJ3MgdmFsdWUgb2Ygc29tZSBjaGFyYWN0ZXJpc3RpYyB1c2luZyBjaGFyYWN0ZXJpc3RpY3Mgb2YgdGhlIG90aGVyIG9ic2VydmF0aW9ucy4gCgohW10oaW1nL2NkcDIucG5nKQoKTGV0J3MgbWFrZSB0aGlzIG1vcmUgY29uY3JldGUuCgpJZiB5b3UgcmVjYWxsIGZyb20gdGhlIFtXaGF0IGFyZSB0aGUgZGF0YT9dKCN3aGF0YXJldGhlZGF0YSkgc2VjdGlvbiBhYm92ZSwgd2hlbiB3ZSBhcmUgdXNpbmcgbWFjaGluZSBsZWFybmluZyBmb3IgcHJlZGljdGlvbiwgb3VyIGRhdGEgY29uc2lzdHMgb2Y6IAoKMS4gQW4gKipjb250aW51b3VzKiogb3V0Y29tZSB2YXJpYWJsZSB0aGF0IHdlIHdhbnQgdG8gcHJlZGljdCAKMi4gQSBzZXQgb2YgZmVhdHVyZShzKSAob3IgcHJlZGljdG9yIHZhcmlhYmxlcykgdGhhdCB3ZSB1c2UgdG8gcHJlZGljdCB0aGUgb3V0Y29tZSB2YXJpYWJsZQoKV2Ugd2lsbCB1c2UgJFkkIHRvIGRlbm90ZSB0aGUgb3V0Y29tZSB2YXJpYWJsZSBhbmQgJFggPSAoWF8xLCBcZG90cywgWF9wKSQgdG8gZGVub3RlICRwJCBkaWZmZXJlbnQgZmVhdHVyZXMgKG9yIHByZWRpY3RvciB2YXJpYWJsZXMpLiAKQmVjYXVzZSBvdXIgb3V0Y29tZSB2YXJpYWJsZSBpcyAqKmNvbnRpbnVvdXMqKiAoYXMgb3Bwb3NlZCB0byBjYXRlZ29yaWNhbCksIHdlIGFyZSBpbnRlcmVzdGVkIGluIGEgcGFydGljdWxhciB0eXBlIG9mIG1hY2hpbmUgbGVhcm5pbmcgYWxnb3JpdGhtLiAKCk91ciBnb2FsIGlzIHRvIGJ1aWxkIGEgbWFjaGluZSBsZWFybmluZyBhbGdvcml0aG0gdGhhdCB1c2VzIHRoZSBmZWF0dXJlcyAkWCQgYXMgaW5wdXQgYW5kIHByZWRpY3RzIGFuIG91dGNvbWUgdmFyaWFibGUgKG9yIGFpciBwb2xsdXRpb24gbGV2ZWxzKSBpbiB0aGUgc2l0dWF0aW9uIHdoZXJlIHdlIGRvIG5vdCBrbm93IHRoZSBvdXRjb21lIHZhcmlhYmxlLiAKClRoZSB3YXkgd2UgZG8gdGhpcyBpcyB0byB1c2UgZGF0YSB3aGVyZSB3ZSBoYXZlIGJvdGggdGhlIGZlYXR1cmVzICQoWF8xPXhfMSwgXGRvdHMgWF9wPXhfcCkkIGFuZCB0aGUgYWN0dWFsIG91dGNvbWUgJFkkIGRhdGEgdG8gX3RyYWluXyBhIG1hY2hpbmUgbGVhcm5pbmcgYWxnb3JpdGhtIHRvIHByZWRpY3QgdGhlIG91dGNvbWUsIHdoaWNoIHdlIGNhbGwgJFxoYXR7WX0kLiAgCgpXaGVuIHdlIHNheSB0cmFpbiBhIG1hY2hpbmUgbGVhcm5pbmcgYWxnb3JpdGhtIHdlIG1lYW4gdGhhdCB3ZSBlc3RpbWF0ZSBhIGZ1bmN0aW9uICRmJCB0aGF0IHVzZXMgdGhlIHByZWRpY3RvciB2YXJpYWJsZXMgJFgkIGFzIGlucHV0IG9yICRcaGF0e1l9ID0gZihYKSQuIAoKIyMgTUwgYXMgYW4gb3B0aW1pemF0aW9uIHByb2JsZW0KCklmIHdlIGFyZSBkb2luZyBhIGdvb2Qgam9iLCB0aGVuIG91ciBwcmVkaWN0ZWQgb3V0Y29tZSAkXGhhdHtZfSQgc2hvdWxkIGNsb3NlbHkgbWF0Y2ggb3VyIGFjdHVhbCBvdXRjb21lICRZJCB0aGF0IHdlIG9ic2VydmVkLiAKCkluIHRoaXMgd2F5LCB3ZSBjYW4gdGhpbmsgb2YgbWFjaGluZSBsZWFybmluZyAoTUwpIGFzIGFuIG9wdGltaXphdGlvbiBwcm9ibGVtIHRoYXQgdHJpZXMgdG8gbWluaW1pemUgdGhlIGRpc3RhbmNlIGJldHdlZW4gJFxoYXR7WX0gPSBmKFgpJCBhbmQgJFkkLiAKCiQkZChZIC0gZihYKSkkJApUaGUgY2hvaWNlIG9mIGRpc3RhbmNlIG1ldHJpYyAkZChcY2RvdCkkIGNhbiBiZSB0aGUgbWVhbiBvZiB0aGUgYWJzb2x1dGUgb3Igc3F1YXJlZCBkaWZmZXJlbmNlIG9yIHNvbWV0aGluZyBtb3JlIGNvbXBsaWNhdGVkLiAKCk11Y2ggb2YgdGhlIGZpZWxkcyBvZiBzdGF0aXN0aWNzIGFuZCBjb21wdXRlciBzY2llbmNlIGFyZSBmb2N1c2VkIG9uIGRlZmluaW5nICRmJCBhbmQgJGQkLgoKIyMgVGhlIHBhcnRzIG9mIGFuIE1MIHByb2JsZW0KClRvIHNldCB1cCBhIG1hY2hpbmUgbGVhcm5pbmcgKE1MKSBwcm9ibGVtLCB3ZSBuZWVkIGEgZmV3IGNvbXBvbmVudHMuClRvIHNvbHZlIGEgKHN0YW5kYXJkKSBtYWNoaW5lIGxlYXJuaW5nIHByb2JsZW0geW91IG5lZWQ6IAoKMS4gQSBkYXRhIHNldCB0byB0cmFpbiBmcm9tLiAKMi4gQW4gYWxnb3JpdGhtIG9yIHNldCBvZiBhbGdvcml0aG1zIHlvdSBjYW4gdXNlIHRvIHRyeSB2YWx1ZXMgb2YgJGYkCjMuIEEgZGlzdGFuY2UgbWV0cmljICRkJCBmb3IgbWVhc3VyaW5nIGhvdyBjbG9zZSAkWSQgaXMgdG8gJFxoYXR7WX0kCjQuIEEgZGVmaW5pdGlvbiBvZiB3aGF0IGEgImdvb2QiIGRpc3RhbmNlIGlzCgpXaGlsZSBlYWNoIG9mIHRoZXNlIGNvbXBvbmVudHMgaXMgYSBfdGVjaG5pY2FsXyBwcm9ibGVtLCB0aGVyZSBoYXMgYmVlbiBhIHRvbiBvZiB3b3JrIGFkZHJlc3NpbmcgdGhvc2UgdGVjaG5pY2FsIGRldGFpbHMuIFRoZSBtb3N0IHByZXNzaW5nIG9wZW4gaXNzdWUgaW4gbWFjaGluZSBsZWFybmluZyBpcyByZWFsaXppbmcgdGhhdCB0aG91Z2ggdGhlc2UgYXJlIF90ZWNobmljYWxfIHN0ZXBzIHRoZXkgYXJlIG5vdCBfb2JqZWN0aXZlXyBzdGVwcy4gSW4gb3RoZXIgd29yZHMsIGhvdyB5b3UgY2hvb3NlIHRoZSBkYXRhLCBhbGdvcml0aG0sIG1ldHJpYywgYW5kIGRlZmluaXRpb24gb2YgImdvb2QiIHNheXMgd2hhdCB5b3UgdmFsdWUgYW5kIGNhbiBkcmFtYXRpY2FsbHkgY2hhbmdlIHRoZSByZXN1bHRzLiBBIGNvdXBsZSBvZiBjYXNlcyB3aGVyZSB0aGlzIHdhcyBhIGJpZyBkZWFsIGFyZTogCgoxLiBbTWFjaGluZSBsZWFybmluZyBmb3IgcmVjaWRpdmlzbV0oaHR0cHM6Ly93d3cucHJvcHVibGljYS5vcmcvYXJ0aWNsZS9tYWNoaW5lLWJpYXMtcmlzay1hc3Nlc3NtZW50cy1pbi1jcmltaW5hbC1zZW50ZW5jaW5nKSAtIHBlb3BsZSBidWlsdCBNTCBtb2RlbHMgdG8gcHJlZGljdCB3aG8gd291bGQgcmUtY29tbWl0IGEgY3JpbWUuIEJ1dCB0aGVzZSBwcmVkaWN0aW9ucyB3ZXJlIGJhc2VkIG9uIGhpc3RvcmljYWxseSBiaWFzZWQgZGF0YSB3aGljaCBsZWQgdG8gYmlhc2VkIHByZWRpY3Rpb25zIGFib3V0IHdobyB3b3VsZCBjb21taXQgbmV3IGNyaW1lcy4gCjIuIFtEZWNpZGluZyBob3cgc2VsZiBkcml2aW5nIGNhcnMgc2hvdWxkIGFjdF0oaHR0cHM6Ly93d3cubmF0dXJlLmNvbS9hcnRpY2xlcy9kNDE1ODYtMDE4LTA3MTM1LTApIC0gc2VsZiBkcml2aW5nIGNhcnMgd2lsbCBoYXZlIHRvIG1ha2UgZGVjaXNpb25zIGFib3V0IGhvdyB0byBkcml2ZSwgd2hvIHRoZXkgbWlnaHQgaW5qdXJlLCBhbmQgaG93IHRvIGF2b2lkIGFjY2lkZW50cy4gRGVwZW5kaW5nIG9uIG91ciBjaG9pY2VzIGZvciAkZiQgYW5kICRkJCB0aGVzZSBtaWdodCBsZWFkIHRvIHdpbGRseSBkaWZmZXJlbnQga2luZHMgb2Ygc2VsZiBkcml2aW5nIGNhcnMuIFRyeSBvdXQgdGhlIFttb3JhbG1hY2hpbmVdKGh0dHA6Ly9tb3JhbG1hY2hpbmUubWl0LmVkdS8pIHRvIHNlZSBob3cgdGhpcyBsb29rcyBpbiBwcmFjdGljZS4gCgpOb3cgdGhhdCB3ZSBrbm93IGEgYml0IG1vcmUgYWJvdXQgbWFjaGluZSBsZWFybmluZywgbGV0J3MgYnVpbGQgYSBtb2RlbCB0byBwcmVkaWN0IGFpciBwb2xsdXRpb24gbGV2ZWxzIHVzaW5nIHRoZSBgdGlkeW1vZGVsc2AgZnJhbWV3b3JrLiAKCiMgKipNYWNoaW5lIGxlYXJuaW5nIHdpdGggYHRpZHltb2RlbHNgKioKKioqClRoZSBnb2FsIGlzIHRvIGJ1aWxkIGEgbWFjaGluZSBsZWFybmluZyBhbGdvcml0aG0gdXNlcyB0aGUgZmVhdHVyZXMgYXMgaW5wdXQgYW5kIHByZWRpY3RzIGEgb3V0Y29tZSB2YXJpYWJsZSAob3IgYWlyIHBvbGx1dGlvbiBsZXZlbHMpIGluIHRoZSBzaXR1YXRpb24gd2hlcmUgd2UgZG8gbm90IGtub3cgdGhlIG91dGNvbWUgdmFyaWFibGUuIAoKVGhlIHdheSB3ZSBkbyB0aGlzIGlzIHRvIHVzZSBkYXRhIHdoZXJlIHdlIGhhdmUgYm90aCB0aGUgaW5wdXQgYW5kIG91dHB1dCBkYXRhIHRvIF90cmFpbl8gYSBtYWNoaW5lIGxlYXJuaW5nIGFsZ29yaXRobS4gCgpUbyB0cmFpbiBhIG1hY2hpbmUgbGVhcm5pbmcgYWxnb3JpdGhtLCB3ZSB3aWxsIHVzZSB0aGUgYHRpZHltb2RlbHNgIHBhY2thZ2UgZWNvc3lzdGVtLiAKCiMjIE92ZXJ2aWV3IAoKIyMjIFRoZSB0aWR5bW9kZWxzIGVjb3N5c3RlbQoKVG8gcGVyZm9ybSBvdXIgYW5hbHlzaXMgd2Ugd2lsbCBiZSB1c2luZyB0aGUgYHRpZHltb2RlbHNgIHN1aXRlIG9mIHBhY2thZ2VzLiAKWW91IG1heSBiZSBmYW1pbGlhciB3aXRoIHRoZSBvbGRlciBwYWNrYWdlcyBgY2FyZXRgIG9yIGBtbHJgIHdoaWNoIGFyZSBhbHNvIGZvciBtYWNoaW5lIGxlYXJuaW5nIGFuZCBtb2RlbGluZyBidXQgYXJlIG5vdCBhIHBhcnQgb2YgdGhlIGB0aWR5dmVyc2VgLiAKW01heCBLdWhuXShodHRwczovL3Jlc291cmNlcy5yc3R1ZGlvLmNvbS9hdXRob3JzL21heC1rdWhuKXt0YXJnZXQ9Il9ibGFuayJ9IGRlc2NyaWJlcyBgdGlkeW1vZGVsc2AgbGlrZSB0aGlzOgoKPiAiT3RoZXIgcGFja2FnZXMsIHN1Y2ggYXMgY2FyZXQgYW5kIG1sciwgaGVscCB0byBzb2x2ZSB0aGUgUiBtb2RlbCBBUEkgaXNzdWUuIFRoZXNlIHBhY2thZ2VzIGRvIGEgbG90IG9mIG90aGVyIHRoaW5ncyB0b286IHByZS1wcm9jZXNzaW5nLCBtb2RlbCB0dW5pbmcsIHJlc2FtcGxpbmcsIGZlYXR1cmUgc2VsZWN0aW9uLCBlbnNlbWJsaW5nLCBhbmQgc28gb24uIEluIHRoZSB0aWR5dmVyc2UsIHdlIHN0cml2ZSB0byBtYWtlIG91ciBwYWNrYWdlcyBtb2R1bGFyIGFuZCBwYXJzbmlwIGlzIGRlc2lnbmVkIG9ubHkgdG8gc29sdmUgdGhlIGludGVyZmFjZSBpc3N1ZS4gSXQgaXMgbm90IGRlc2lnbmVkIHRvIGJlIGEgZHJvcC1pbiByZXBsYWNlbWVudCBmb3IgY2FyZXQuClRoZSB0aWR5bW9kZWxzIHBhY2thZ2UgY29sbGVjdGlvbiwgd2hpY2ggaW5jbHVkZXMgcGFyc25pcCwgaGFzIG90aGVyIHBhY2thZ2VzIGZvciBtYW55IG9mIHRoZXNlIHRhc2tzLCBhbmQgdGhleSBhcmUgZGVzaWduZWQgdG8gd29yayB0b2dldGhlci4gV2UgYXJlIHdvcmtpbmcgdG93YXJkcyBoaWdoZXItbGV2ZWwgQVBJcyB0aGF0IGNhbiByZXBsaWNhdGUgYW5kIGV4dGVuZCB3aGF0IHRoZSBjdXJyZW50IG1vZGVsIHBhY2thZ2VzIGNhbiBkby4iCgpUaGVyZSBhcmUgbWFueSBSIHBhY2thZ2VzIGluIHRoZSBgdGlkeW1vZGVsc2AgZWNvc3lzdGVtLCB3aGljaCBhc3Npc3Qgd2l0aCB2YXJpb3VzIHN0ZXBzIGluIHRoZSBwcm9jZXNzIG9mIGJ1aWxkaW5nIGEgbWFjaGluZSBsZWFybmluZyBhbGdvcml0aG0uIFRoZXNlIGFyZSB0aGUgbWFpbiBwYWNrYWdlcywgYnV0IHRoZXJlIGFyZSBvdGhlcnMuCgpgYGB7ciwgZWNobz1GQUxTRSwgb3V0LndpZHRoPSI4MDBweCJ9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltZyIsInNpbXBsZXRpZHltb2RlbHMucG5nIikpCmBgYAoKVGhpcyBpcyBhIHNjaGVtYXRpYyBvZiBob3cgdGhlc2UgcGFja2FnZXMgd29yayB0b2dldGhlciB0byBidWlsZCBhIG1hY2hpbmUgbGVhcm5pbmcgYWxnb3JpdGhtOgoKYGBge3IsIGVjaG89RkFMU0UsIG91dC53aWR0aD0iODAwcHgifQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbWciLCJNYWNoaW5lTGVhcm5pbmcucG5nIikpCmBgYAoKIyMjIEJlbmVmaXRzIG9mIHRpZHltb2RlbHMgIAoKVGhlIHR3byBtYWpvciBiZW5lZml0cyBvZiBgdGlkeW1vZGVsc2AgYXJlOiAKCjEuIFN0YW5kYXJkaXplZCB3b3JrZmxvdy9mb3JtYXQvbm90YXRpb24gYWNyb3NzIGRpZmZlcmVudCB0eXBlcyBvZiBtYWNoaW5lIGxlYXJuaW5nIGFsZ29yaXRobXMgIAoKRGlmZmVyZW50IG5vdGF0aW9ucyBhcmUgcmVxdWlyZWQgZm9yIGRpZmZlcmVudCBhbGdvcml0aG1zIGFzIHRoZSBhbGdvcml0aG1zIGhhdmUgYmVlbiBkZXZlbG9wZWQgYnkgZGlmZmVyZW50IHBlb3BsZS4gVGhpcyB3b3VsZCByZXF1aXJlIHRoZSBwYWluc3Rha2luZyBwcm9jZXNzIG9mIHJlZm9ybWF0dGluZyB0aGUgZGF0YSB0byBiZSBjb21wYXRpYmxlIHdpdGggZWFjaCBhbGdvcml0aG0gaWYgbXVsdGlwbGUgYWxnb3JpdGhtcyB3ZXJlIHRlc3RlZC4KCjIuIENhbiBlYXNpbHkgbW9kaWZ5IHByZS1wcm9jZXNzaW5nLCBhbGdvcml0aG0gY2hvaWNlLCBhbmQgaHlwZXItcGFyYW1ldGVyIHR1bmluZyBtYWtpbmcgb3B0aW1pemF0aW9uIGVhc3kgIAoKTW9kaWZ5aW5nIGEgcGllY2Ugb2YgdGhlIG92ZXJhbGwgcHJvY2VzcyBpcyBub3cgZWFzaWVyIHRoYW4gYmVmb3JlIGJlY2F1c2UgbWFueSBvZiB0aGUgc3RlcHMgYXJlIHNwZWNpZmllZCB1c2luZyB0aGUgYHRpZHltb2RlbHNgIHBhY2thZ2VzIGluIGEgY29udmVuaWVudCBtYW5uZXIuIFRodXMgdGhlIGVudGlyZSBwcm9jZXNzIGNhbiBiZSByZXJ1biBhZnRlciBhIHNpbXBsZSBjaGFuZ2UgdG8gcHJlLXByb2Nlc3Npbmcgd2l0aG91dCBtdWNoIGRpZmZpY3VsdHkuCgoKCiMjIFNwbGl0dGluZyB0aGUgZGF0YQoKVGhlIGZpcnN0IHN0ZXAgYWZ0ZXIgZGF0YSBleHBsb3JhdGlvbiBpbiBtYWNoaW5lIGxlYXJuaW5nIGFuYWx5c2lzIGlzIHRvIFtzcGxpdCB0aGUgZGF0YV0oaHR0cHM6Ly90b3dhcmRzZGF0YXNjaWVuY2UuY29tL3RyYWluLXZhbGlkYXRpb24tYW5kLXRlc3Qtc2V0cy03MmNiNDBjYmE5ZTcpe3RhcmdldD0iX2JsYW5rIn0gaW50byAqKnRyYWluaW5nKiogYW5kICoqdGVzdGluZyoqIGRhdGEgc2V0cy4gCgpUaGUgdHJhaW5pbmcgZGF0YSBzZXQgd2lsbCBiZSB1c2VkIHRvIGJ1aWxkIGFuZCB0dW5lIG91ciBtb2RlbC4gClRoaXMgaXMgdGhlIGRhdGEgdGhhdCB0aGUgbW9kZWwgImxlYXJucyIgb24uIApUaGUgdGVzdGluZyBkYXRhIHNldCB3aWxsIGJlIHVzZWQgdG8gZXZhbHVhdGUgdGhlIHBlcmZvcm1hbmNlIG9mIG91ciBtb2RlbCBpbiBhIG1vcmUgZ2VuZXJhbGl6YWJsZSB3YXkuIFdoYXQgZG8gd2UgbWVhbiBieSAiZ2VuZXJhbGl6YWJsZSI/CgpSZW1lbWJlciB0aGF0IG91ciBtYWluIGdvYWwgaXMgdG8gdXNlIG91ciBtb2RlbCB0byBiZSBhYmxlIHRvIHByZWRpY3QgYWlyIHBvbGx1dGlvbiBsZXZlbHMgaW4gYXJlYXMgd2hlcmUgdGhlcmUgYXJlIG5vIGdyYXZpbWV0cmljIG1vbml0b3JzLiAKClRoZXJlZm9yZSwgaWYgb3VyIG1vZGVsIGlzIHJlYWxseSBnb29kIGF0IHByZWRpY3RpbmcgYWlyIHBvbGx1dGlvbiB3aXRoIHRoZSBkYXRhIHRoYXQgd2UgdXNlIHRvIGJ1aWxkIGl0LCBpdCBtaWdodCBub3QgZG8gdGhlIGJlc3Qgam9iIGZvciB0aGUgYXJlYXMgd2hlcmUgdGhlcmUgYXJlIGZldyB0byBubyBtb25pdG9ycy4gCgpUaGlzIHdvdWxkIGNhdXNlIHVzIHRvIGhhdmUgcmVhbGx5IGdvb2QgcHJlZGljdGlvbiBhY2N1cmFjeSBhbmQgd2UgbWlnaHQgYXNzdW1lIHRoYXQgd2Ugd2VyZSBnb2luZyB0byBkbyBhIGdvb2Qgam9iIGVzdGltYXRpbmcgYWlyIHBvbGx1dGlvbiBhbnkgdGltZSB3ZSB1c2Ugb3VyIG1vZGVsLCBidXQgaW4gZmFjdCB0aGlzIHdvdWxkIGxpa2VseSBub3QgYmUgdGhlIGNhc2UuIApUaGlzIHNpdHVhdGlvbiBpcyB3aGF0IHdlIGNhbGwgKipbb3ZlcmZpdHRpbmddKGh0dHBzOi8vdG93YXJkc2RhdGFzY2llbmNlLmNvbS90cmFpbi10ZXN0LXNwbGl0LWFuZC1jcm9zcy12YWxpZGF0aW9uLWluLXB5dGhvbi04MGI2MWJlY2E0YjYpe3RhcmdldD0iX2JsYW5rIn0gKiouCgpPdmVyZml0dGluZyBoYXBwZW5zIHdoZW4gd2UgZW5kIHVwIG1vZGVsaW5nIG5vdCBvbmx5IHRoZSBtYWpvciByZWxhdGlvbnNoaXBzIGluIG91ciBkYXRhIGJ1dCBhbHNvIHRoZSBub2lzZSB3aXRoaW4gb3VyIGRhdGEuIAoKYGBge3IsIGVjaG89RkFMU0V9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJodHRwczovL21pcm8ubWVkaXVtLmNvbS9tYXgvMTExMC8xKnRCRXJYWVZ2VHcyalNVWUs3dGhVMkEucG5nIikKYGBgCgojIyMjIyBbW3NvdXJjZV1dKGh0dHBzOi8vbWlyby5tZWRpdW0uY29tL21heC8xMTEwLzEqdEJFclhZVnZUdzJqU1VZSzd0aFUyQS5wbmcpe3RhcmdldD0iX2JsYW5rIn0KCklmIHdlIGdldCBnb29kIHByZWRpY3Rpb24gd2l0aCBvdXIgdGVzdGluZyBzZXQsIHRoZW4gd2Uga25vdyB0aGF0IG91ciBtb2RlbCBjYW4gYmUgYXBwbGllZCB0byBvdGhlciBkYXRhIGFuZCB3aWxsIGxpa2VseSBwZXJmb3JtIHdlbGwuIFdlIHdpbGwgZGlzY3VzcyB0aGlzIG1vcmUgbGF0ZXIuCgpXZSB3aWxsIG5vdCB0b3VjaCB0aGUgdGVzdGluZyBzZXQgdW50aWwgd2UgaGF2ZSBjb21wbGV0ZWQgb3B0aW1pemluZyBvdXIgbW9kZWwgd2l0aCB0aGUgdHJhaW5pbmcgc2V0LiAKVGhpcyB3aWxsIGFsbG93IHVzIHRvIGhhdmUgYSBsZXNzIGJpYXNlZCBldmFsdWF0aW9uIG9mIGhvdyB3ZWxsIG91ciBtb2RlbCBjYW4gZG8gd2l0aCBvdGhlciBkYXRhIGJlc2lkZXMgdGhlIGRhdGEgdXNlZCBpbiB0aGUgdHJhaW5pbmcgc2V0IHRvIGJ1aWxkIHRoZSBtb2RlbC4gCklkZWFsbHksIHlvdSB3b3VsZCBhbHNvIHdhbnQgYSBjb21wbGV0ZWx5IGluZGVwZW5kZW50IGRhdGEgc2V0IHRvIGZ1cnRoZXIgdGVzdCB0aGUgcGVyZm9ybWFuY2Ugb2YgeW91ciBtb2RlbC4KClRvIHNwbGl0IHRoZSBkYXRhIGludG8gdHJhaW5pbmcgYW5kIHRlc3RpbmcsIHdlIHdpbGwgdXNlIHRoZSBgaW5pdGlhbF9zcGxpdCgpYCBmdW5jdGlvbiBpbiB0aGUgYHJzYW1wbGVgIHBhY2thZ2UgdG8gc3BlY2lmeSBob3cgd2Ugd2FudCB0byBzcGxpdCBvdXIgZGF0YS4KCgpgYGB7ciwgZWNobz1GQUxTRX0KCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltZyIsInNwbGl0LnBuZyIpKQpgYGAKCmBgYHtyfQpzZXQuc2VlZCgxMjM0KQpwbV9zcGxpdCA8LSByc2FtcGxlOjppbml0aWFsX3NwbGl0KGRhdGEgPSBwbSwgcHJvcCA9IDIvMykKcG1fc3BsaXQKYGBgCgpBIGNvdXBsZSBvZiBub3RlcyBmcm9tIHRoZSBjb2RlIGFib3ZlOiAKCi0gVHlwaWNhbGx5LCBkYXRhIGFyZSBzcGxpdCBpbnRvIDMvNCBvZiB0aGUgb2JzZXJ2YXRpb25zIGZvciB0cmFpbmluZyBhbmQgMS80IGZvciB0ZXN0aW5nLiBUaGlzIGlzIHRoZSBkZWZhdWx0IHByb3BvcnRpb24gYW5kIGRvZXMgbm90IG5lZWQgdG8gYmUgc3BlY2lmaWVkLiBIb3dldmVyLCB5b3UgY2FuIGNoYW5nZSB0aGUgcHJvcG9ydGlvbiB1c2luZyB0aGUgYHByb3BgIGFyZ3VtZW50LCB3aGljaCB3ZSB3aWxsIGRvIHRoYXQgaGVyZSBmb3IgaWxsdXN0cmF0aXZlIHB1cnBvc2VzLgotIFNpbmNlIHRoZSBzcGxpdCBpcyBwZXJmb3JtZWQgcmFuZG9tbHksIGl0IGlzIGEgZ29vZCBpZGVhIHRvIHVzZSB0aGUgYHNldC5zZWVkKClgIGZ1bmN0aW9uIGluIGJhc2UgUiB0byBlbnN1cmUgdGhhdCBpZiB5b3VyIHJlcnVuIHlvdXIgY29kZSB0aGF0IHlvdXIgc3BsaXQgd2lsbCBiZSB0aGUgc2FtZSBuZXh0IHRpbWUuCi0gV2UgY2FuIHNlZSB0aGUgbnVtYmVyIG9mIG1vbml0b3JzIGluIG91ciB0cmFpbmluZywgdGVzdGluZywgYW5kIG9yaWdpbmFsIGRhdGEgYnkgdHlwaW5nIGluIHRoZSBuYW1lIG9mIG91ciBzcGxpdCBvYmplY3QuIFRoZSByZXN1bHQgd2lsbCBsb29rIGxpa2UgdGhpczoKPHRyYWluaW5nIGRhdGEgc2FtcGxlIG51bWJlciwgdGVzdGluZyBkYXRhIHNhbXBsZSBudW1iZXIsIG9yaWdpbmFsIHNhbXBsZSBudW1iZXI+IAoKTm93LCB5b3UgY2FuIGFsc28gc3BlY2lmeSBhIHZhcmlhYmxlIHRvIHN0cmF0aWZ5IGJ5IHdpdGggdGhlIGBzdHJhdGFgIGFyZ3VtZW50LiAKVGhpcyBpcyB1c2VmdWwgaWYgeW91IGhhdmUgaW1iYWxhbmNlZCBjYXRlZ29yaWNhbCB2YXJpYWJsZXMgYW5kIHlvdSB3b3VsZCBsaWtlIHRvIGludGVudGlvbmFsbHkgbWFrZSBzdXJlIHRoYXQgdGhlcmUgYXJlIHNpbWlsYXIgbnVtYmVyIG9mIHNhbXBsZXMgb2YgdGhlIHJhcmVyIGNhdGVnb3JpZXMgaW4gYm90aCB0aGUgdGVzdGluZyBhbmQgdHJhaW5pbmcgc2V0cy4gCk90aGVyd2lzZSB0aGUgc3BsaXQgaXMgcGVyZm9ybWVkIHJhbmRvbWx5LiAKCkFjY29yZGluZyB0byB0aGUgW2RvY3VtZW50YXRpb25dKGh0dHBzOi8vd3d3LnJkb2N1bWVudGF0aW9uLm9yZy9wYWNrYWdlcy9yc2FtcGxlL3ZlcnNpb25zLzAuMC41L3RvcGljcy9pbml0aWFsX3NwbGl0KSBmb3IgdGhlIGByc2FtcGxlYCBwYWNrYWdlOgoKPiBUaGUgc3RyYXRhIGFyZ3VtZW50IGNhdXNlcyB0aGUgcmFuZG9tIHNhbXBsaW5nIHRvIGJlIGNvbmR1Y3RlZCB3aXRoaW4gdGhlIHN0cmF0aWZpY2F0aW9uIHZhcmlhYmxlLiBUaGlzIGNhbiBoZWxwIGVuc3VyZSB0aGF0IHRoZSBudW1iZXIgb2YgZGF0YSBwb2ludHMgaW4gdGhlIHRyYWluaW5nIGRhdGEgaXMgZXF1aXZhbGVudCB0byB0aGUgcHJvcG9ydGlvbnMgaW4gdGhlIG9yaWdpbmFsIGRhdGEgc2V0LgoKSW4gdGhlIGNhc2Ugd2l0aCBvdXIgZGF0YSBzZXQsIHBlcmhhcHMgd2Ugd291bGQgbGlrZSBvdXIgdHJhaW5pbmcgc2V0IHRvIGhhdmUgc2ltaWxhciBwcm9wb3J0aW9ucyBvZiBtb25pdG9ycyBmcm9tIGVhY2ggb2YgdGhlIHN0YXRlcyBhcyBpbiB0aGUgaW5pdGlhbCBkYXRhLiAKVGhpcyBtaWdodCBiZSB1c2VmdWwgaWYgd2Ugd2FudCBvdXIgbW9kZWwgdG8gYmUgZ2VuZXJhbGl6YWJsZSBhY3Jvc3MgYWxsIG9mIHRoZSBzdGF0ZXMuCgpXZSBjYW4gc2VlIHRoYXQgaW5kZWVkIHRoZXJlIGFyZSBkaWZmZXJlbnQgcHJvcG9ydGlvbnMgb2YgbW9uaXRvcnMgaW4gZWFjaCBzdGF0ZSBieSB1c2luZyB0aGUgYGNvdW50KClgIGZ1bmN0aW9uIG9mIHRoZSBgZHBseXJgIHBhY2thZ2UuIAoKYGBge3IsIGV2YWwgPSBGQUxTRX0KY291bnQocG0sIHN0YXRlKQpgYGAKClNjcm9sbCB0aHJvdWdoIHRoZSBvdXRwdXQ6CgojIyMjIHsuc2Nyb2xsYWJsZSB9CgpgYGB7ciwgZWNobz1GQUxTRX0KIyBTY3JvbGwgdGhyb3VnaCB0aGUgb3V0cHV0IQpjb3VudChwbSwgc3RhdGUpICU+JQogIHByaW50KG4gPSAxZTMpCmBgYAojIyMjCgpJZiBvdXIgZGF0YSBzZXQgd2VyZSBsYXJnZSBlbm91Z2ggaXQgbWlnaHQgYmUgbmljZSB0aGVuIHRvIHN0cmF0aWZ5IGJ5IHN0YXRlIHVzaW5nIHRoZSBgc3RyYXRhID0gInN0YXRlImAgYXJndW1lbnQgaW4gYGluaXRpYWxfc3BsaXQoKWAsIGJ1dCBvdXIgZGF0YSBpcyB1bmZvcnR1bmF0ZWx5IG5vdCBsYXJnZSBlbm91Z2guIAoKSW1wb3J0YW50bHkgdGhlIGBpbml0aWFsX3NwbGl0YCBmdW5jdGlvbiBvbmx5IGRldGVybWluZXMgd2hhdCByb3dzIG9mIG91ciBgcG1gIGRhdGEgZnJhbWUgc2hvdWxkIGJlIGFzc2lnbmVkIGZvciB0cmFpbmluZyBvciB0ZXN0aW5nLCBpdCBkb2VzIG5vdCBhY3R1YWxseSBzcGxpdCB0aGUgZGF0YS4gCgpUbyBleHRyYWN0IHRoZSB0ZXN0aW5nIGFuZCB0cmFpbmluZyBkYXRhIHdlIGNhbiB1c2UgdGhlIGB0cmFpbmluZygpYCBhbmQgYHRlc3RpbmcoKWAgZnVuY3Rpb25zIGFsc28gb2YgdGhlIGByc2FtcGxlYCBwYWNrYWdlLgoKIyMjIyB7LnNjcm9sbGFibGUgfQpgYGB7cn0KdHJhaW5fcG0gPC1yc2FtcGxlOjp0cmFpbmluZyhwbV9zcGxpdCkKdGVzdF9wbSA8LXJzYW1wbGU6OnRlc3RpbmcocG1fc3BsaXQpCiAKIyBTY3JvbGwgdGhyb3VnaCB0aGUgb3V0cHV0IQpjb3VudCh0cmFpbl9wbSwgc3RhdGUpCmNvdW50KHRlc3RfcG0sIHN0YXRlKQpgYGAKIyMjIwoKCgojIyBQcmVwYXJyaW5nIGZvciBwcmUtcHJvY2Vzc2luZyB0aGUgZGF0YQoKQWZ0ZXIgc3BsaXR0aW5nIHRoZSBkYXRhLCB0aGUgbmV4dCBzdGVwIGlzIHRvIHByb2Nlc3MgdGhlIHRyYWluaW5nIGFuZCB0ZXN0aW5nIGRhdGEgc28gdGhhdCB0aGUgZGF0YSBhcmUgYXJlIGNvbXBhdGlibGUgYW5kIG9wdGltaXplZCB0byBiZSB1c2VkIHdpdGggdGhlIG1vZGVsLiAKVGhpcyBpbnZvbHZlcyBhc3NpZ25pbmcgdmFyaWFibGVzIHRvIHNwZWNpZmljIHJvbGVzIHdpdGhpbiB0aGUgbW9kZWwgYW5kIHByZS1wcm9jZXNzaW5nIGxpa2Ugc2NhbGluZyB2YXJpYWJsZXMgYW5kIHJlbW92aW5nIHJlZHVuZGFudCB2YXJpYWJsZXMuIApUaGlzIHByb2Nlc3MgaXMgYWxzbyBjYWxsZWQgZmVhdHVyZSBlbmdpbmVlcmluZy4KClRvIGRvIHRoaXMgaW4gYHRpZHltb2RlbHNgLCB3ZSB3aWxsIGNyZWF0ZSB3aGF0J3MgY2FsbGVkIGEgInJlY2lwZSIgdXNpbmcgdGhlIGByZWNpcGVzYCBwYWNrYWdlLCB3aGljaCBpcyBhIHN0YW5kYXJkaXplZCBmb3JtYXQgZm9yIGEgc2VxdWVuY2Ugb2Ygc3RlcHMgZm9yIHByZS1wcm9jZXNzaW5nIHRoZSBkYXRhLgpUaGlzIGNhbiBiZSB2ZXJ5IHVzZWZ1bCBiZWNhdXNlIGl0IG1ha2VzIHRlc3Rpbmcgb3V0IGRpZmZlcmVudCBwcmUtcHJvY2Vzc2luZyBzdGVwcyBvciBkaWZmZXJlbnQgYWxnb3JpdGhtcyB3aXRoIHRoZSBzYW1lIHByZS1wcm9jZXNzaW5nIHZlcnkgZWFzeSBhbmQgcmVwcm9kdWNpYmxlLgpDcmVhdGluZyBhIHJlY2lwZSBzcGVjaWZpZXMgKipob3cgYSBkYXRhIGZyYW1lIG9mIHByZWRpY3RvcnMgc2hvdWxkIGJlIGNyZWF0ZWQqKiAtIGl0IHNwZWNpZmllcyB3aGF0IHZhcmlhYmxlcyB0byBiZSB1c2VkIGFuZCB0aGUgcHJlLXByb2Nlc3Npbmcgc3RlcHMsIGJ1dCBpdCAqKmRvZXMgbm90IGV4ZWN1dGUgdGhlc2Ugc3RlcHMqKiBvciBjcmVhdGUgdGhlIGRhdGEgZnJhbWUgb2YgcHJlZGljdG9ycy4KCiMjIyBTdGVwIDE6IFNwZWNpZnkgdmFyaWFibGVzIHJvbGVzIHdpdGggYHJlY2lwZSgpYCBmdW5jdGlvbgoKVGhlIGZpcnN0IHRoaW5nIHRvIGRvIHRvIGNyZWF0ZSBhIHJlY2lwZSBpcyB0byBzcGVjaWZ5IHdoaWNoIHZhcmlhYmxlcyB3ZSB3aWxsIGJlIHVzaW5nIGFzIG91ciBvdXRjb21lIGFuZCBwcmVkaWN0b3JzIHVzaW5nIHRoZSBgcmVjaXBlKClgIGZ1bmN0aW9uLiAKSW4gdGVybXMgb2YgdGhlIG1ldGFwaG9yIG9mIGJha2luZywgd2UgY2FuIHRoaW5rIG9mIHRoaXMgYXMgbGlzdGluZyBvdXIgaW5ncmVkaWVudHMuIApUcmFuc2xhdGluZyB0aGlzIHRvIHRoZSBgcmVjaXBlc2AgcGFja2FnZSwgd2UgdXNlIHRoZSBgcmVjaXBlKClgIGZ1bmN0aW9uIHRvIGFzc2lnbiByb2xlcyB0byBhbGwgdGhlIHZhcmlhYmxlcy4gCgpMZXQncyB0cnkgdGhlIHNpbXBsZXN0IHJlY2lwZSB3aXRoIG5vIHByZS1wcm9jZXNzaW5nIHN0ZXBzOiBzaW1wbHkgbGlzdCB0aGUgb3V0Y29tZSBhbmQgcHJlZGljdG9yIHZhcmlhYmxlcy4KCldlIGNhbiBkbyBzbyBpbiB0d28gd2F5czogIAoKMSkgVXNpbmcgZm9ybXVsYSBub3RhdGlvbiAgCjIpIEFzc2lnbmluZyByb2xlcyB0byBlYWNoIHZhcmlhYmxlICAKCkxldCdzIGxvb2sgYXQgdGhlIGZpcnN0IHdheSB1c2luZyBmb3JtdWxhIG5vdGF0aW9uLCB3aGljaCBsb29rcyBsaWtlIHRoaXM6ICAKCm91dGNvbWUocykgfiBwcmVkaWN0b3IocykgIAoKSWYgaW4gdGhlIGNhc2Ugb2YgbXVsdGlwbGUgcHJlZGljdG9ycyBvciBhIG11bHRpdmFyaWF0ZSBzaXR1YXRpb24gd2l0aCB0d28gb3V0Y29tZXMsIHVzZSBhIHBsdXMgc2lnbjogIAoKb3V0Y29tZTEgKyBvdXRjb21lMiB+IHByZWRpY3RvcjEgKyBwcmVkaWN0b3IyICAKCklmIHdlIHdhbnQgdG8gaW5jbHVkZSBhbGwgcHJlZGljdG9ycyB3ZSBjYW4gdXNlIGEgcGVyaW9kIGxpa2Ugc286ICAKCm91dGNvbWVfdmFyaWFibGVfbmFtZSB+IC4gIAoKTm93IHdpdGggb3VyIGRhdGEsIHdlIHdpbGwgc3RhcnQgYnkgbWFraW5nIGEgcmVjaXBlIGZvciBvdXIgdHJhaW5pbmcgZGF0YS4KSWYgeW91IHJlY2FsbCwgdGhlIGNvbnRpbnVvdXMgb3V0Y29tZSB2YXJpYWJsZSBpcyBgdmFsdWVgICh0aGUgYXZlcmFnZSBhbm51YWwgZ3JhdmltZXRyaWMgbW9uaXRvciBQTX4yLjV+IGNvbmNlbnRyYXRpb24gaW4gdWcvbV4zXikuIApPdXIgZmVhdHVyZXMgKG9yIHByZWRpY3RvciB2YXJpYWJsZXMpIGFyZSBhbGwgdGhlIG90aGVyIHZhcmlhYmxlcyBleGNlcHQgdGhlIG1vbml0b3IgSUQsIHdoaWNoIGlzIGFuIGBpZGAgdmFyaWFibGUuCgpUaGUgcmVhc29uIG5vdCB0byBpbmNsdWRlIHRoZSBgaWRgIHZhcmlhYmxlIGlzIGJlY2F1c2UgdGhpcyB2YXJpYWJsZSBpbmNsdWRlcyB0aGUgY291bnR5IG51bWJlciBhbmQgYSBudW1iZXIgZGVzaWduYXRpbmcgd2hpY2ggcGFydGljdWxhciBtb25pdG9yIHRoZSB2YWx1ZXMgY2FtZSBmcm9tIChvZiB0aGUgbW9uaXRvcnMgdGhlcmUgYXJlIGluIHRoYXQgY291bnR5KS4gClNpbmNlIHRoaXMgbnVtYmVyIGlzIGFyYml0cmFyeSBhbmQgdGhlIGNvdW50eSBpbmZvcm1hdGlvbiBpcyBhbHNvIGdpdmVuIGluIHRoZSBkYXRhLCBhbmQgdGhlIGZhY3QgdGhhdCBlYWNoIG1vbml0b3Igb25seSBoYXMgb25lIHZhbHVlIGluIHRoZSBgdmFsdWVgIHZhcmlhYmxlLCBub3RoaW5nIGlzIGdhaW5lZCBieSBpbmNsdWRpbmcgdGhpcyB2YXJpYWJsZSBhbmQgaXQgbWF5IGluc3RlYWQgaW50cm9kdWNlIG5vaXNlLiAKSG93ZXZlciwgaXQgaXMgdXNlZnVsIHRvIGtlZXAgdGhpcyBkYXRhIHRvIHRha2UgYSBsb29rIGF0IHdoYXQgaXMgaGFwcGVuaW5nIGxhdGVyLiAKV2Ugd2lsbCBzaG93IHlvdSB3aGF0IHRvIGRvIGluIHRoaXMgY2FzZSBpbiBqdXN0IGEgYml0LgoKSW4gdGhlIHNpbXBsZXN0IGNhc2UsIHdlIG1pZ2h0IHVzZSBhbGwgcHJlZGljdG9ycyBsaWtlIHRoaXM6CgpgYGB7cn0Kc2ltcGxlX3JlYyA8LSB0cmFpbl9wbSAlPiUKICByZWNpcGVzOjpyZWNpcGUodmFsdWUgfiAuKQoKc2ltcGxlX3JlYwpgYGAKCldlIHNlZSBhIHJlY2lwZSBoYXMgYmVlbiBjcmVhdGVkIHdpdGggMSBvdXRjb21lIHZhcmlhYmxlIGFuZCA0OSBwcmVkaWN0b3IgdmFyaWFibGVzIChvciBmZWF0dXJlcykuIApBbHNvLCBub3RpY2UgaG93IHdlIG5hbWVkIHRoZSBvdXRwdXQgb2YgYHJlY2lwZSgpYC4gClRoZSBuYW1pbmcgY29udmVudGlvbiBmb3IgcmVjaXBlIG9iamVjdHMgaXMgYCpfcmVjYCBvciBgcmVjYC4gCgpOb3csIGxldCdzIGdldCBiYWNrIHRvIHRoZSBgaWRgIHZhcmlhYmxlLiAKSW5zdGVhZCBvZiBpbmNsdWRpbmcgaXQgYXMgYSBwcmVkaWN0b3IgdmFyaWFibGUsIHdlIGNvdWxkIGFsc28gdXNlIHRoZSBgdXBkYXRlX3JvbGUoKWAgZnVuY3Rpb24gb2YgdGhlIGByZWNpcGVzYCBwYWNrYWdlLgoKYGBge3J9CnNpbXBsZV9yZWMgPC0gdHJhaW5fcG0gJT4lCiAgcmVjaXBlczo6cmVjaXBlKHZhbHVlIH4gLikgJT4lCiAgcmVjaXBlczo6dXBkYXRlX3JvbGUoaWQsIG5ld19yb2xlID0gImlkIHZhcmlhYmxlIikKCnNpbXBsZV9yZWMKYGBgCgo8ZGV0YWlscz48c3VtbWFyeT4gQ2xpY2sgaGVyZSBsZWFybiBtb3JlIGFib3V0IHRoZSB3b3JraW5nIHdpdGggYGlkYCB2YXJpYWJsZXMgPC9zdW1tYXJ5PgoKVGhpcyBvcHRpb24gd29ya3Mgd2VsbCB3aXRoIHRoZSBuZXdlciBgd29ya2Zsb3dzYCBwYWNrYWdlLCBob3dldmVyIGBpZGAgdmFyaWFibGVzIGFyZSBvZnRlbiBkcm9wcGVkIGZyb20gYW5hbHlzZXMgdGhhdCBkbyBub3QgdXNlIHRoaXMgbmV3ZXIgcGFja2FnZSBhcyB0aGV5IGNhbiBtYWtlIHRoZSBwcm9jZXNzIGRpZmZpY3VsdCB3aXRoIHVzaW5nIHRoZSBgcGFyc25pcGAgcGFja2FnZSBhbG9uZSBkdWUgdG8gdGhlIGZhY3QgdGhhdCBuZXcgbGV2ZWxzIChvciBwb3NzaWJsZSB2YWx1ZXMpIG1heSBiZSBpbnRyb2R1Y2VkIHdpdGggdGhlIHRlc3RpbmcgZGF0YS4KCjwvZGV0YWlscz4KCldlIGNvdWxkIGFsc28gc3BlY2lmeSB0aGUgb3V0Y29tZSBhbmQgcHJlZGljdG9ycyBpbiB0aGUgc2FtZSB3YXkgYXMgd2UganVzdCBzcGVjaWZpZWQgdGhlIGlkIHZhcmlhYmxlLiAKUGxlYXNlIHNlZSBbaGVyZV0oaHR0cHM6Ly90aWR5bW9kZWxzLmdpdGh1Yi5pby9yZWNpcGVzL3JlZmVyZW5jZS9yZWNpcGUuaHRtbCl7dGFyZ2V0PSJfYmxhbmsifSBmb3IgZXhhbXBsZXMgb2Ygb3RoZXIgcm9sZXMgZm9yIHZhcmlhYmxlcy4gClRoZSByb2xlIGNhbiBiZSBhY3R1YWxseSBiZSBhbnkgdmFsdWUuIAoKVGhlIG9yZGVyIGlzIGltcG9ydGFudCBoZXJlLCBhcyB3ZSBmaXJzdCBtYWtlIGFsbCB2YXJpYWJsZXMgcHJlZGljdG9ycyBhbmQgdGhlbiBvdmVycmlkZSB0aGlzIHJvbGUgZm9yIHRoZSBvdXRjb21lIGFuZCBgaWRgIHZhcmlhYmxlLiAKV2Ugd2lsbCB1c2UgdGhlIGBldmVyeXRoaW5nKClgIGZ1bmN0aW9uIG9mIHRoZSBgZHBseXJgIHBhY2thZ2UgdG8gc3RhcnQgd2l0aCBhbGwgb2YgdGhlIHZhcmlhYmxlcyBpbiBgdHJhaW5fcG1gLgoKYGBge3J9CnNpbXBsZV9yZWMgPC1yZWNpcGUodHJhaW5fcG0pICU+JQogICAgdXBkYXRlX3JvbGUoZXZlcnl0aGluZygpLCBuZXdfcm9sZSA9ICJwcmVkaWN0b3IiKSU+JQogICAgdXBkYXRlX3JvbGUodmFsdWUsIG5ld19yb2xlID0gIm91dGNvbWUiKSU+JQogICAgdXBkYXRlX3JvbGUoaWQsIG5ld19yb2xlID0gImlkIHZhcmlhYmxlIikKCnNpbXBsZV9yZWMKYGBgCgpJZiB3ZSB3YW50IHRvIHRha2UgYSBsb29rIGF0IG91ciBmb3JtdWxhIGZyb20gb3VyIHJlY2lwZSwgd2UgY2FuIGRvIHVzZSB0aGUgYGZvcm11bGEoKWAgZnVuY3Rpb24gb2YgdGhlIGBzdGF0c2AgcGFja2FnZS4KCmBgYHtyfQpmb3JtdWxhKHNpbXBsZV9yZWMpCmBgYAoKV2UgY2FuIGFsc28gdmlldyBvdXIgcmVjaXBlIGluIG1vcmUgZGV0YWlsIHVzaW5nIHRoZSBiYXNlIGBzdW1tYXJ5KClgIGZ1bmN0aW9uLgoKYGBge3J9CnN1bW1hcnkoc2ltcGxlX3JlYykKYGBgCgpUbyBzdW1tYXJpemUgdGhpcyBzdGVwLCB3ZSB1c2UgdGhlIGByZWNpcGUoKWAgZnVuY3Rpb24gdG8gYXNzaWduIHJvbGVzIHRvIGFsbCB0aGUgdmFyaWFibGVzOiAKCmBgYHtyLCBlY2hvPUZBTFNFLCBvdXQud2lkdGg9IjQwMHB4In0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1nIiwiU3RhcnRpbmdfYV9yZWNpcGVfcmVjaXBlczEucG5nIikpCmBgYAoKCiMjIyBTdGVwIDI6IFNwZWNpZnkgdGhlIHByZS1wcm9jZXNzaW5nIHN0ZXBzIHdpdGggYHN0ZXAqKClgIGZ1bmN0aW9ucwoKTmV4dCwgd2UgdXNlIHRoZSBgc3RlcCooKWAgZnVuY3Rpb25zIGZyb20gdGhlIGByZWNpcGVgIHBhY2thZ2UgdG8gc3BlY2lmeSBwcmUtcHJvY2Vzc2luZyBzdGVwcy4gCgpgYGB7ciwgZWNobz1GQUxTRSwgb3V0LndpZHRoPSI0MDBweCJ9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltZyIsIk1ha2luZ19hX3JlY2lwZV9yZWNpcGVzMi5wbmciKSkKYGBgCgoqKlRoaXMgW2xpbmtdKGh0dHBzOi8vdGlkeW1vZGVscy5naXRodWIuaW8vcmVjaXBlcy9yZWZlcmVuY2UvaW5kZXguaHRtbCl7dGFyZ2V0PSJfYmxhbmsifSBhbmQgdGhpcyBbbGlua10oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL3JlY2lwZXMvcmVjaXBlcy5wZGYpe3RhcmdldD0iX2JsYW5rIn0gc2hvdyB0aGUgbWFueSBvcHRpb25zIGZvciByZWNpcGUgc3RlcCBmdW5jdGlvbnMuKioKCjx1PlRoZXJlIGFyZSBzdGVwIGZ1bmN0aW9ucyBmb3IgYSB2YXJpZXR5IG9mIHB1cnBvc2VzOjwvdT4KCjEuIFsqKkltcHV0YXRpb24qKl0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSW1wdXRhdGlvbl8oc3RhdGlzdGljcykpe3RhcmdldD0iX2JsYW5rIn0gLS0gZmlsbGluZyBpbiBtaXNzaW5nIHZhbHVlcyBiYXNlZCBvbiB0aGUgZXhpc3RpbmcgZGF0YSAKMi4gWyoqVHJhbnNmb3JtYXRpb24qKl0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRGF0YV90cmFuc2Zvcm1hdGlvbl8oc3RhdGlzdGljcykpe3RhcmdldD0iX2JsYW5rIn0gLS0gY2hhbmdpbmcgYWxsIHZhbHVlcyBvZiBhIHZhcmlhYmxlIGluIHRoZSBzYW1lIHdheSwgdHlwaWNhbGx5IHRvIG1ha2UgaXQgbW9yZSBub3JtYWwgb3IgZWFzaWVyIHRvIGludGVycHJldAozLiBbKipEaXNjcmV0aXphdGlvbioqXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9EaXNjcmV0aXphdGlvbl9vZl9jb250aW51b3VzX2ZlYXR1cmVzKXt0YXJnZXQ9Il9ibGFuayJ9IC0tIGNvbnZlcnRpbmcgY29udGludW91cyB2YWx1ZXMgaW50byBkaXNjcmV0ZSBvciBub21pbmFsIHZhbHVlcyAtIGJpbm5pbmcgZm9yIGV4YW1wbGUgdG8gcmVkdWNlIHRoZSBudW1iZXIgb2YgcG9zc2libGUgbGV2ZWxzIChIb3dldmVyIHRoaXMgaXMgZ2VuZXJhbGx5IG5vdCBhZHZpc2FibGUhKQo0LiBbKipFbmNvZGluZyAvIENyZWF0aW5nIER1bW15IFZhcmlhYmxlcyoqXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9EdW1teV92YXJpYWJsZV8oc3RhdGlzdGljcykpe3RhcmdldD0iX2JsYW5rIn0gLS0gY3JlYXRpbmcgYSBudW1lcmljIGNvZGUgZm9yIGNhdGVnb3JpY2FsIHZhcmlhYmxlcwooWyoqTW9yZSBvbiBEdW1teSBWYXJpYWJsZXMgYW5kIG9uZSBob3QgZW5jb2RpbmcqKl0oaHR0cHM6Ly9tZWRpdW0uY29tL3AvYjU4NDBiZTNjNDFhL3Jlc3BvbnNlcy9zaG93KXt0YXJnZXQ9Il9ibGFuayJ9KQo1LiBbKipEYXRhIHR5cGUgY29udmVyc2lvbnMqKl0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL2hhYmxhci92aWduZXR0ZXMvY29udmVydC5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9ICAtLSB3aGljaCBtZWFucyBjaGFuZ2luZyBmcm9tIGludGVnZXIgdG8gZmFjdG9yIG9yIG51bWVyaWMgdG8gZGF0ZSBldGMuCjYuIFsqKkludGVyYWN0aW9uKipdKGh0dHBzOi8vc3RhdGlzdGljc2J5amltLmNvbS9yZWdyZXNzaW9uL2ludGVyYWN0aW9uLWVmZmVjdHMvKXt0YXJnZXQ9Il9ibGFuayJ9ICB0ZXJtIGFkZGl0aW9uIHRvIHRoZSBtb2RlbCAtLSB3aGljaCBtZWFucyB0aGF0IHdlIHdvdWxkIGJlIG1vZGVsaW5nIGZvciBwcmVkaWN0b3JzIHRoYXQgd291bGQgaW5mbHVlbmNlIHRoZSBjYXBhY2l0eSBvZiBlYWNoIG90aGVyIHRvIHByZWRpY3QgdGhlIG91dGNvbWUKNy4gWyoqTm9ybWFsaXphdGlvbioqXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Ob3JtYWxpemF0aW9uXyhzdGF0aXN0aWNzKSl7dGFyZ2V0PSJfYmxhbmsifSAtLSBjZW50ZXJpbmcgYW5kIHNjYWxpbmcgdGhlIGRhdGEgdG8gYSBzaW1pbGFyIHJhbmdlIG9mIHZhbHVlcwo4LiBbKipEaW1lbnNpb25hbGl0eSBSZWR1Y3Rpb24vIFNpZ25hbCBFeHRyYWN0aW9uKipdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0RpbWVuc2lvbmFsaXR5X3JlZHVjdGlvbil7dGFyZ2V0PSJfYmxhbmsifSAtLSByZWR1Y2luZyB0aGUgc3BhY2Ugb2YgZmVhdHVyZXMgb3IgcHJlZGljdG9ycyB0byBhIHNtYWxsZXIgc2V0IG9mIHZhcmlhYmxlcyB0aGF0IGNhcHR1cmUgdGhlIHZhcmlhdGlvbiBvciBzaWduYWwgaW4gdGhlIG9yaWdpbmFsIHZhcmlhYmxlcyAoZXguIFByaW5jaXBhbCBDb21wb25lbnQgQW5hbHlzaXMgYW5kIEluZGVwZW5kZW50IENvbXBvbmVudCBBbmFseXNpcykKOS4gKipGaWx0ZXJpbmcqKiAtLSBmaWx0ZXJpbmcgb3B0aW9ucyBmb3IgcmVtb3ZpbmcgdmFyaWFibGVzIChleC4gcmVtb3ZlIHZhcmlhYmxlcyB0aGF0IGFyZSBoaWdobHkgY29ycmVsYXRlZCB0byBvdGhlcnMgb3IgcmVtb3ZlIHZhcmlhYmxlcyB3aXRoIHZlcnkgbGl0dGxlIHZhcmlhbmNlIGFuZCB0aGVyZWZvcmUgbGlrZWx5IGxpdHRsZSBwcmVkaWN0aXZlIGNhcGFjaXR5KQoxMC4gWyoqUm93IG9wZXJhdGlvbnMqKl0oaHR0cHM6Ly90YXJ0YXJ1cy5vcmcvZ2FyZXRoL21hdGhzL0xpbmVhcl9BbGdlYnJhL3Jvd19vcGVyYXRpb25zLnBkZil7dGFyZ2V0PSJfYmxhbmsifSAtLSBwZXJmb3JtaW5nIGZ1bmN0aW9ucyBvbiB0aGUgdmFsdWVzIHdpdGhpbiB0aGUgcm93cyAgKGV4LiByZWFycmFuZ2luZywgZmlsdGVyaW5nLCBpbXB1dGluZykKMTEuICoqQ2hlY2tpbmcgZnVuY3Rpb25zKiogLS0gU2FuaXR5IGNoZWNrcyB0byBsb29rIGZvciBtaXNzaW5nIHZhbHVlcywgdG8gbG9vayBhdCB0aGUgdmFyaWFibGUgY2xhc3NlcyBldGMuCgpBbGwgb2YgdGhlIHN0ZXAgZnVuY3Rpb25zIGxvb2sgbGlrZSBgc3RlcF8qKClgIHdpdGggdGhlIGAqYCByZXBsYWNlZCB3aXRoIGEgbmFtZSwgZXhjZXB0IGZvciB0aGUgY2hlY2sgZnVuY3Rpb25zIHdoaWNoIGxvb2sgbGlrZSBgY2hlY2tfKigpYC4KClRoZXJlIGFyZSBzZXZlcmFsIHdheXMgdG8gc2VsZWN0IHdoYXQgdmFyaWFibGVzIHRvIGFwcGx5IHN0ZXBzIHRvOiAgCgoxLiBVc2luZyBgdGlkeXNlbGVjdGAgbWV0aG9kczogYGNvbnRhaW5zKClgLCBgbWF0Y2hlcygpYCwgYHN0YXJ0c193aXRoKClgLCBgZW5kc193aXRoKClgLCBgZXZlcnl0aGluZygpYCwgYG51bV9yYW5nZSgpYCAgCjIuIFVzaW5nIHRoZSB0eXBlOiBgYWxsX25vbWluYWwoKWAsIGBhbGxfbnVtZXJpYygpYCAsIGBoYXNfdHlwZSgpYCAKMy4gVXNpbmcgdGhlIHJvbGU6IGBhbGxfcHJlZGljdG9ycygpYCwgYGFsbF9vdXRjb21lcygpYCwgYGhhc19yb2xlKClgCjQuIFVzaW5nIHRoZSBuYW1lIC0gdXNlIHRoZSBhY3R1YWwgbmFtZSBvZiB0aGUgdmFyaWFibGUvdmFyaWFibGVzIG9mIGludGVyZXN0ICAKCkxldCdzIHRyeSBhZGRpbmcgc29tZSBzdGVwcyB0byBvdXIgcmVjaXBlLgoKCldlIG1pZ2h0IHdhbnQgdG8gcG90ZW50aWFsbHkgW29uZSBob3QgZW5jb2RlXShodHRwczovL21hY2hpbmVsZWFybmluZ21hc3RlcnkuY29tL3doeS1vbmUtaG90LWVuY29kZS1kYXRhLWluLW1hY2hpbmUtbGVhcm5pbmcvKXt0YXJnZXQ9Il9ibGFuayJ9IHNvbWUgb2Ygb3VyIGNhdGVnb3JpY2FsIHZhcmlhYmxlcyBzbyB0aGF0IHRoZXkgY2FuIGJlIHVzZWQgd2l0aCBjZXJ0YWluIGFsZ29yaXRobXMuIAoKV2UgY2FuIGRvIHRoaXMgd2l0aCB0aGUgYHN0ZXBfZHVtbXkoKWAgZnVuY3Rpb24gYW5kIHRoZSBgb25lX2hvdCA9IFRSVUVgIGFyZ3VtZW50LiAKT25lIGhvdCBlbmNvZGluZyBtZWFucyB0aGF0IHdlIGRvIG5vdCBzaW1wbHkgZW5jb2RlIG91ciBjYXRlZ29yaWNhbCB2YXJpYWJsZXMgbnVtZXJpY2FsbHksIGFzIG91ciBudW1lcmljIGFzc2lnbm1lbnRzIGNhbiBiZSBpbnRlcnByZXRlZCBieSBhbGdvcml0aG1zIGFzIGhhdmluZyBhIHBhcnRpY3VsYXIgcmFuayBvciBvcmRlci4gCkluc3RlYWQsIGJpbmFyeSB2YXJpYWJsZXMgbWFkZSBvZiAxcyBhbmQgMHMgYXJlIHVzZWQgdG8gYXJiaXRyYXJpbHkgYXNzaWduIGEgbnVtZXJpYyB2YWx1ZSB0aGF0IGhhcyBubyBhcHBhcmVudCBvcmRlci4KCmBgYHtyfQpzaW1wbGVfcmVjICU+JQogIHN0ZXBfZHVtbXkoc3RhdGUsIGNvdW50eSwgY2l0eSwgemN0YSwgb25lX2hvdCA9IFRSVUUpCmBgYAoKT3VyIGBmaXBzYCB2YXJpYWJsZSBpbmNsdWRlcyBhIG51bWVyaWMgY29kZSBmb3Igc3RhdGUgYW5kIGNvdW50eSAtIGFuZCB0aGVyZWZvcmUgaXMgZXNzZW50aWFsbHkgYSBwcm94eSBmb3IgY291bnR5LgpTaW5jZSB3ZSBhbHJlYWR5IGhhdmUgY291bnR5LCB3ZSB3aWxsIGp1c3QgdXNlIGl0IGFuZCBrZWVwIHRoZSBgZmlwc2AgSUQgYXMgYW5vdGhlciBJRCB2YXJpYWJsZS4KCldlIGNhbiByZW1vdmUgdGhlIGBmaXBzYCB2YXJpYWJsZSBmcm9tIHRoZSBwcmVkaWN0b3JzIHVzaW5nIGB1cGRhdGVfcm9sZSgpYCB0byBtYWtlIHN1cmUgdGhhdCB0aGUgcm9sZSBpcyBubyBsb25nZXIgYCJwcmVkaWN0b3IiYC4gCldlIGNhbiBtYWtlIHRoZSByb2xlIGFueXRoaW5nIHdlIHdhbnQgYWN0dWFsbHksIHNvIHdlIHdpbGwga2VlcCBpdCBzb21ldGhpbmcgaWRlbnRpZmlhYmxlLgoKYGBge3J9CnNpbXBsZV9yZWMgJT4lCiAgdXBkYXRlX3JvbGUoImZpcHMiLCBuZXdfcm9sZSA9ICJjb3VudHkgaWQiKQpgYGAKCldlIG1pZ2h0IGFsc28gd2FudCB0byByZW1vdmUgdmFyaWFibGVzIHRoYXQgYXBwZWFyIHRvIGJlIHJlZHVuZGFudCBhbmQgYXJlIGhpZ2hseSBjb3JyZWxhdGVkIHdpdGggb3RoZXJzLCBhcyB3ZSBrbm93IGZyb20gb3VyIGV4cGxvcmF0b3J5IGRhdGEgYW5hbHlzaXMgdGhhdCBtYW55IG9mIG91ciB2YXJpYWJsZXMgYXJlIGNvcnJlbGF0ZWQgd2l0aCBvbmUgYW5vdGhlci4gCldlIGNhbiBkbyB0aGlzIHVzaW5nIHRoZSBgc3RlcF9jb3JyKClgIGZ1bmN0aW9uLgoKV2UgZG9uJ3Qgd2FudCB0byByZW1vdmUgc29tZSBvZiBvdXIgdmFyaWFibGVzLCBsaWtlIHRoZSBgQ01BUWAgYW5kIGBhb2RgIHZhcmlhYmxlcywgd2UgY2FuIHNwZWNpZnkgdGhpcyB1c2luZyB0aGUgYC1gIHNpZ24gYmVmb3JlIHRoZSBuYW1lcyBvZiB0aGVzZSB2YXJpYWJsZXMgbGlrZSBzbzoKCmBgYHtyfQpzaW1wbGVfcmVjICU+JQogIHN0ZXBfY29ycihhbGxfcHJlZGljdG9ycygpLCAtIENNQVEsIC0gYW9kKQpgYGAKCgpJdCBpcyBhbHNvIGEgZ29vZCBpZGVhIHRvIHJlbW92ZSB2YXJpYWJsZXMgd2l0aCBuZWFyLXplcm8gdmFyaWFuY2UsIHdoaWNoIGNhbiBiZSBkb25lIHdpdGggdGhlIGBzdGVwX256digpYCBmdW5jdGlvbi4gCgpWYXJpYWJsZXMgaGF2ZSBsb3cgdmFyaWFuY2UgaWYgYWxsIHRoZSB2YWx1ZXMgYXJlIHZlcnkgc2ltaWxhciwgdGhlIHZhbHVlcyBhcmUgdmVyeSBzcGFyc2UsIG9yIGlmIHRoZXkgYXJlIGhpZ2hseSBpbWJhbGFuY2VkLiBBZ2FpbiB3ZSBkb24ndCB3YW50IHRvIHJlbW92ZSBvdXIgYENNQVFgIGFuZCBgYW9kYCB2YXJpYWJsZXMuCgpgYGB7cn0Kc2ltcGxlX3JlYyAlPiUKICBzdGVwX256dihhbGxfcHJlZGljdG9ycygpLCAtIENNQVEsIC0gYW9kKQpgYGAKCjxkZXRhaWxzPjxzdW1tYXJ5PiBDbGljayBoZXJlIHRvIGxlYXJuIGFib3V0IGV4YW1wbGVzIHdoZXJlIHlvdSBtaWdodCBoYXZlIG5lYXItemVybyB2YXJpYW5jZSB2YXJpYWJsZXM8L3N1bW1hcnk+CgoxKSAqKlNpbWlsYXIgVmFsdWVzKiogLSBJZiB0aGUgcG9wdWxhdGlvbiBkZW5zaXR5IHdhcyBuZWFybHkgdGhlIHNhbWUgZm9yIGV2ZXJ5IHpjdGEgdGhhdCBjb250YWluZWQgYSBtb25pdG9yLCB0aGVuIGtub3dpbmcgdGhlIHBvcHVsYXRpb24gZGVuc2l0eSBuZWFyIG91ciBtb25pdG9yIHdvdWxkIGNvbnRyaWJ1dGUgbGl0dGxlIHRvIG91ciBtb2RlbCBpbiBhc3Npc3RpbmcgdXMgdG8gcHJlZGljdCBtb25pdG9yIGFpciBwb2xsdXRpb24gdmFsdWVzLiAKMikgKipTcGFyc2UgRGF0YSoqIC0gSWYgYWxsIG9mIHRoZSBtb25pdG9ycyB3ZXJlIGluIGxvY2F0aW9ucyB3aGVyZSB0aGUgcG9wdWxhdGlvbnMgZGlkIG5vdCBhdHRlbmQgZ3JhZHVhdGUgc2Nob29sLCB0aGVuIHRoZXNlIHZhbHVlcyB3b3VsZCBtb3N0bHkgYmUgemVybywgYWdhaW4gdGhpcyB3b3VsZCBkbyB2ZXJ5IGxpdHRsZSB0byBoZWxwIHVzIGRpc3Rpbmd1aXNoIG91ciBhaXIgcG9sbHV0aW9uIG1vbml0b3JzLldoZW4gbWFueSBvZiB0aGUgdmFsdWVzIGFyZSB6ZXJvIHRoaXMgaXMgYWxzbyBjYWxsZWQgc3BhcnNlIGRhdGEuICAKMykgKipJbWJhbGFuY2VkIERhdGEqKiBJZiBuZWFybHkgYWxsIG9mIHRoZSBtb25pdG9ycyB3ZXJlIGxvY2F0ZWQgaW4gb25lIHBhcnRpY3VsYXIgc3RhdGUsIGFuZCBhbGwgdGhlIG90aGVycyBvbmx5IGhhZCBvbmUgbW9uaXRvciBlYWNoLCB0aGVuIHRoZSByZWFsIHByZWRpY3RpdmUgdmFsdWUgd291bGQgc2ltcGx5IGJlIGluIGtub3dpbmcgaWYgYSBtb25pdG9yIGlzIGxvY2F0ZWQgaW4gdGhhdCBwYXJ0aWN1bGFyIHN0YXRlIG9yIG5vdC4gSW4gdGhpcyBjYXNlIHdlIGRvbid0IHdhbnQgdG8gcmVtb3ZlIG91ciB2YXJpYWJsZSwgd2UganVzdCB3YW50IHRvIHNpbXBsaWZ5IGl0LgoKU2VlIHRoaXMgW2Jsb2cgcG9zdF0oaHR0cHM6Ly93d3cuci1ibG9nZ2Vycy5jb20vbmVhci16ZXJvLXZhcmlhbmNlLXByZWRpY3RvcnMtc2hvdWxkLXdlLXJlbW92ZS10aGVtLyl7dGFyZ2V0PSJfYmxhbmsifSBhYm91dCB3aHkgcmVtb3ZpbmcgbmVhci16ZXJvIHZhcmlhbmNlIHZhcmlhYmxlcyBpc24ndCBhbHdheXMgYSBnb29kIGlkZWEgaWYgd2UgdGhpbmsgdGhhdCBhIHZhcmlhYmxlIG1pZ2h0IGJlIGVzcGVjaWFsbHkgaW5mb3JtYXRpdmUuCgo8L2RldGFpbHM+CgpMZXQncyBwdXQgYWxsIHRoaXMgdG9nZXRoZXIgbm93LiAKCioqUmVtZW1iZXI6IGl0IGlzIGltcG9ydGFudCB0byBhZGQgdGhlIHN0ZXBzIHRvIHRoZSByZWNpcGUgaW4gYW4gb3JkZXIgdGhhdCBtYWtlcyBzZW5zZSBqdXN0IGxpa2Ugd2l0aCBhIGNvb2tpbmcgcmVjaXBlLioqCgpGaXJzdCwgd2UgYXJlIGdvaW5nIHRvIGNyZWF0ZSBudW1lcmljIHZhbHVlcyBmb3Igb3VyIGNhdGVnb3JpY2FsIHZhcmlhYmxlcywgdGhlbiB3ZSB3aWxsIGxvb2sgYXQgY29ycmVsYXRpb24gYW5kIG5lYXItemVybyB2YXJpYW5jZS4gCkFnYWluLCB3ZSBkbyBub3Qgd2FudCB0byByZW1vdmUgdGhlIGBDTUFRYCBhbmQgYGFvZGAgdmFyaWFibGVzLCBzbyB3ZSBjYW4gbWFrZSBzdXJlIHRoZXkgYXJlIGtlcHQgaW4gdGhlIG1vZGVsIGJ5IGV4Y2x1ZGluZyB0aGVtIGZyb20gdGhvc2Ugc3RlcHMuIApJZiB3ZSBzcGVjaWZpY2FsbHkgd2FudGVkIHRvIHJlbW92ZSBhIHByZWRpY3RvciB3ZSBjb3VsZCB1c2UgYHN0ZXBfcm0oKWAuCgpgYGB7cn0Kc2ltcGxlX3JlYyAlPD4lCiAgdXBkYXRlX3JvbGUoImZpcHMiLCBuZXdfcm9sZSA9ICJjb3VudHkgaWQiKSAlPiUKICBzdGVwX2R1bW15KHN0YXRlLCBjb3VudHksIGNpdHksIHpjdGEsIG9uZV9ob3QgPSBUUlVFKSAlPiUKICBzdGVwX2NvcnIoYWxsX3ByZWRpY3RvcnMoKSwgLSBDTUFRLCAtIGFvZCklPiUKICBzdGVwX256dihhbGxfcHJlZGljdG9ycygpLCAtIENNQVEsIC0gYW9kKQogIApzaW1wbGVfcmVjCmBgYAoKCgojIyBSdW5uaW5nIHRoZSBwcmUtcHJvY2Vzc2luZwoKIyMjIFN0ZXAgMTogVXBkYXRlIHRoZSByZWNpcGUgd2l0aCB0cmFpbmluZyBkYXRhIHVzaW5nIGBwcmVwKClgCgpUaGUgbmV4dCBtYWpvciBmdW5jdGlvbiBvZiB0aGUgYHJlY2lwZXNgIHBhY2thZ2UgaXMgYHByZXAoKWAuClRoaXMgZnVuY3Rpb24gdXBkYXRlcyB0aGUgcmVjaXBlIG9iamVjdCBiYXNlZCBvbiB0aGUgdHJhaW5pbmcgZGF0YS4gCkl0IGVzdGltYXRlcyBwYXJhbWV0ZXJzIChlc3RpbWF0aW5nIHRoZSByZXF1aXJlZCBxdWFudGl0aWVzIGFuZCBzdGF0aXN0aWNzIHJlcXVpcmVkIGJ5IHRoZSBzdGVwcyBmb3IgdGhlIHZhcmlhYmxlcykgZm9yIHByZS1wcm9jZXNzaW5nIGFuZCB1cGRhdGVzIHRoZSB2YXJpYWJsZXMgcm9sZXMsIGFzIHNvbWUgb2YgdGhlIHByZWRpY3RvcnMgbWF5IGJlIHJlbW92ZWQsIHRoaXMgYWxsb3dzIHRoZSByZWNpcGUgdG8gYmUgcmVhZHkgdG8gdXNlIG9uIG90aGVyIGRhdGEgc2V0cy4gCkl0ICoqZG9lcyBub3QgbmVjZXNzYXJpbHkgYWN0dWFsbHkgZXhlY3V0ZSB0aGUgcHJlLXByb2Nlc3NpbmcgaXRzZWxmKiosIGhvd2V2ZXIgd2Ugd2lsbCBzcGVjaWZ5IGluIGFyZ3VtZW50IGZvciBpdCB0byBkbyB0aGlzIHNvIHRoYXQgd2UgY2FuIHRha2UgYSBsb29rIGF0IHRoZSBwcmUtcHJvY2Vzc2VkIGRhdGEuCgoKVGhlcmUgYXJlIHNvbWUgaW1wb3J0YW50IGFyZ3VtZW50cyB0byBrbm93IGFib3V0OgoKMS4gYHRyYWluaW5nYCAtIHlvdSBtdXN0IHN1cHBseSBhIHRyYWluaW5nIGRhdGEgc2V0IHRvIGVzdGltYXRlIHBhcmFtZXRlcnMgZm9yIHByZS1wcm9jZXNzaW5nIG9wZXJhdGlvbnMgKHJlY2lwZSBzdGVwcykgLSB0aGlzIG1heSBhbHJlYWR5IGJlIGluY2x1ZGVkIGluIHlvdXIgcmVjaXBlIC0gYXMgaXMgdGhlIGNhc2UgZm9yIHVzCjIuIGBmcmVzaGAgLSBpZiBgZnJlc2g9VFJVRWAsIC0gd2lsbCByZXRyYWluIGFuZCBlc3RpbWF0ZSBwYXJhbWV0ZXJzIGZvciBhbnkgcHJldmlvdXMgc3RlcHMgdGhhdCB3ZXJlIGFscmVhZHkgcHJlcHBlZCBpZiB5b3UgYWRkIG1vcmUgc3RlcHMgdG8gdGhlIHJlY2lwZQozLiBgdmVyYm9zZWAgLSBpZiBgdmVyYm9zZT1UUlVFYCwgc2hvd3MgdGhlIHByb2dyZXNzIGFzIHRoZSBzdGVwcyBhcmUgZXZhbHVhdGVkIGFuZCB0aGUgc2l6ZSBvZiB0aGUgcHJlLXByb2Nlc3NlZCB0cmFpbmluZyBzZXQKNC4gYHJldGFpbmAgLSBpZiBgcmV0YWluPVRSVUVgLCB0aGVuIHRoZSBwcmUtcHJvY2Vzc2VkIHRyYWluaW5nIHNldCB3aWxsIGJlIHNhdmVkIHdpdGhpbiB0aGUgcmVjaXBlIChhcyB0ZW1wbGF0ZSkuIFRoaXMgaXMgZ29vZCBpZiB5b3UgYXJlIGxpa2VseSB0byBhZGQgbW9yZSBzdGVwcyBhbmQgZG8gbm90IHdhbnQgdG8gcmVydW4gdGhlIGBwcmVwKClgIG9uIHRoZSBwcmV2aW91cyBzdGVwcy4gSG93ZXZlciB0aGlzIGNhbiBtYWtlIHRoZSByZWNpcGUgc2l6ZSBsYXJnZS4gVGhpcyBpcyBuZWNlc3NhcnkgaWYgeW91IHdhbnQgdG8gYWN0dWFsbHkgbG9vayBhdCB0aGUgcHJlLXByb2Nlc3NlZCBkYXRhLgoKTGV0J3MgdHJ5IG91dCB0aGUgYHByZXAoKWAgZnVuY3Rpb246IAoKYGBge3J9CnByZXBwZWRfcmVjIDwtIHByZXAoc2ltcGxlX3JlYywgdmVyYm9zZSA9IFRSVUUsIHJldGFpbiA9IFRSVUUgKQpuYW1lcyhwcmVwcGVkX3JlYykKYGBgCgpUaGVyZSBhcmUgYWxzbyBsb3RzIG9mIHVzZWZ1bCB0aGluZ3MgdG8gY2hlY2tvdXQgaW4gdGhlIG91dHB1dCBvZiBgcHJlcCgpYC4KWW91IGNhbiBzZWU6CgoxLiB0aGUgYHN0ZXBzYCB0aGF0IHdlcmUgcnVuICAKMi4gdGhlIG9yaWdpbmFsIHZhcmlhYmxlIGluZm8gKGB2YXJfaW5mb2ApICAKMy4gdGhlIHVwZGF0ZWQgdmFyaWFibGUgaW5mbyBhZnRlciBwcmUtcHJvY2Vzc2luZyAoYHRlcm1faW5mb2ApCjQuIHRoZSBuZXcgYGxldmVsc2Agb2YgdGhlIHZhcmlhYmxlcyAKNS4gdGhlIG9yaWdpbmFsIGxldmVscyBvZiB0aGUgdmFyaWFibGVzIChgb3JpZ19sdmxzYCkKNi4gaW5mbyBhYm91dCB0aGUgdHJhaW5pbmcgZGF0YSBzZXQgc2l6ZSBhbmQgY29tcGxldGVuZXNzIChgdHJfaW5mb2ApCgoqKk5vdGUqKjogWW91IG1heSBzZWUgdGhlIGBwcmVwLnJlY2lwZSgpYCBmdW5jdGlvbiBpbiBtYXRlcmlhbCB0aGF0IHlvdSByZWFkIGFib3V0IHRoZSBgcmVjaXBlc2AgcGFja2FnZS4gVGhpcyBpcyByZWZlcnJpbmcgdG8gdGhlIGBwcmVwKClgIGZ1bmN0aW9uIG9mIHRoZSBgcmVjaXBlc2AgcGFja2FnZS4KCgojIyMgU3RlcCAyOiBFeHRyYWN0IHByZS1wcm9jZXNzZWQgdHJhaW5pbmcgZGF0YSB1c2luZyBganVpY2UoKWAKClNpbmNlIHdlIHJldGFpbmVkIG91ciBwcmUtcHJvY2Vzc2VkIHRyYWluaW5nIGRhdGEgKGkuZS4gYHByZXAocmV0YWluPVRSVUUpYCksIHdlIGNhbiB0YWtlIGEgbG9vayBhdCBpdCBsaWtlIGJ5IHVzaW5nIHRoZSBganVpY2UoKWAgZnVuY3Rpb24gb2YgdGhlIGByZWNpcGVzYCBwYWNrYWdlIGxpa2UgdGhpczoKCmBgYHtyLCBlY2hvPUZBTFNFLCBvdXQud2lkdGg9IjQwMHB4In0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1nIiwidHJhaW5pbmdfcHJlcHJvY2Vzc2luZ19yZWNpcGVzMy5wbmciKSkKYGBgCgpMZXQncyBqdWljZSEgCgoKIyMjIyB7LnNjcm9sbGFibGUgfQpgYGB7cn0KIyBTY3JvbGwgdGhyb3VnaCB0aGUgb3V0cHV0IQpqdWljZWRfdHJhaW4gPC0ganVpY2UocHJlcHBlZF9yZWMpCmdsaW1wc2UoanVpY2VkX3RyYWluKQpgYGAKIyMjIwoKCkZvciBlYXN5IGNvbXBhcmlzb24gc2FrZSAtIGhlcmUgaXMgb3VyIG9yaWdpbmFsIGRhdGE6CgojIyMjIHsuc2Nyb2xsYWJsZSB9CgpgYGB7cn0KIyBTY3JvbGwgdGhyb3VnaCB0aGUgb3V0cHV0IQpnbGltcHNlKHBtKQpgYGAKIyMjIwoKTm90aWNlIGhvdyB3ZSBvbmx5IGhhdmUgMzYgdmFyaWFibGVzIG5vdyBpbnN0ZWFkIG9mIDUwISAKVHdvIG9mIHRoZXNlIGFyZSBvdXIgSUQgdmFyaWFibGVzIChgZmlwc2AgYW5kIHRoZSBhY3R1YWwgbW9uaXRvciBJRCAoYGlkYCkpIGFuZCBvbmUgaXMgb3VyIG91dGNvbWUgKGB2YWx1ZWApLiAKVGh1cyB3ZSBvbmx5IGhhdmUgMzMgcHJlZGljdG9ycyBub3cuIApXZSBjYW4gYWxzbyBzZWUgdGhhdCB2YXJpYWJsZXMgdGhhdCB3ZSBubyBsb25nZXIgaGF2ZSBhbnkgY2F0ZWdvcmljYWwgdmFyaWFibGVzLiAKVmFyaWFibGVzIGxpa2UgYHN0YXRlYCBhcmUgZ29uZSBhbmQgb25seSBgc3RhdGVfQ2FsaWZvcm5pYWAgcmVtYWlucyBhcyBpdCB3YXMgdGhlIG9ubHkgc3RhdGUgaWRlbnRpdHkgdG8gaGF2ZSBub256ZXJvIHZhcmlhbmNlLgpXZSBjYW4gYWxzbyBzZWUgdGhhdCB0aGVyZSB3ZXJlIG1vcmUgbW9uaXRvcnMgbGlzdGVkIGFzIGAiTm90IGluIGEgY2l0eSJgIHRoYW4gYW55IGNpdHkuIAoKV2UgY2FuIHNlZSB0aGF0IENhbGlmb3JuaWEgaGFkIHRoZSBsYXJnZXN0IG51bWJlciBvZiBtb25pdG9ycyBjb21wYXJlZCB0byB0aGUgb3RoZXIgc3RhdGVzLgoKYGBge3IsIGV2YWwgPSBGQUxTRX0KcG0gJT4lIGNvdW50KHN0YXRlKSAKYGBgCgoKU2Nyb2xsIHRocm91Z2ggdGhlIG91dHB1dDoKCiMjIyMgey5zY3JvbGxhYmxlIH0KCmBgYHtyLCBlY2hvID0gRkFMU0V9CnBtICU+JSBjb3VudChzdGF0ZSkgICU+JQogIHByaW50KG4gPSAxZTMpCmBgYAoKIyMjIwoKYGBge3IsIGV2YWwgPSBGQUxTRX0KcG0gJT4lIGNvdW50KGNpdHkpCmBgYAoKU2Nyb2xsIHRocm91Z2ggdGhlIG91dHB1dDoKCiMjIyMgey5zY3JvbGxhYmxlIH0KCmBgYHtyLCBlY2hvPUZBTFNFfQpwbSAlPiUgY291bnQoY2l0eSkgJT4lCiAgcHJpbnQobiA9IDFlMykKYGBgCgojIyMjCgoqKk5vdGUqKjogUmVjYWxsIHRoYXQgeW91IG11c3Qgc3BlY2lmeSBgcmV0YWluID0gVFJVRWAgYXJndW1lbnQgb2YgdGhlIGBwcmVwKClgIGZ1bmN0aW9uIHRvIHVzZSBganVpY2UoKWAuCgojIyMgU3RlcCAzOiBFeHRyYWN0IHByZS1wcm9jZXNzZWQgdGVzdGluZyBkYXRhIHVzaW5nIGBiYWtlKClgCgpBY2NvcmRpbmcgdG8gdGhlIGB0aWR5bW9kZWxzYCBkb2N1bWVudGF0aW9uOgoKPiBgYmFrZSgpYCB0YWtlcyBhIHRyYWluZWQgcmVjaXBlIGFuZCBhcHBsaWVzIHRoZSBvcGVyYXRpb25zIHRvIGEgZGF0YSBzZXQgdG8gY3JlYXRlIGEgZGVzaWduIG1hdHJpeC4KIEZvciBleGFtcGxlOiBpdCBhcHBsaWVzIHRoZSBjZW50ZXJpbmcgdG8gbmV3IGRhdGEgc2V0cyB1c2luZyB0aGVzZSBtZWFucyB1c2VkIHRvIGNyZWF0ZSB0aGUgcmVjaXBlCgpUaGVyZWZvcmUsIGlmIHlvdSB3YW50ZWQgdG8gbG9vayBhdCB0aGUgcHJlLXByb2Nlc3NlZCB0ZXN0aW5nIGRhdGEgeW91IHdvdWxkIHVzZSB0aGUgYGJha2UoKWAgZnVuY3Rpb24gb2YgdGhlIGByZWNpcGVzYCBwYWNrYWdlLgooWW91IGdlbmVyYWxseSB3YW50IHRvIGxlYXZlIHlvdXIgdGVzdGluZyBkYXRhIGFsb25lLCBidXQgaXQgaXMgZ29vZCB0byBsb29rIGZvciBpc3N1ZXMgbGlrZSB0aGUgaW50cm9kdWN0aW9uIG9mIE5BIHZhbHVlcykuCgpgYGB7ciwgZWNobz1GQUxTRSwgb3V0LndpZHRoPSI0MDBweCJ9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltZyIsInRlc3RpbmdfcHJlcHJvY2Vzc2luZ19yZWNpcGVzNC5wbmciKSkKYGBgCgpMZXQncyBiYWtlISAKCiMjIyMgey5zY3JvbGxhYmxlIH0KYGBge3IsfQojIFNjcm9sbCB0aHJvdWdoIHRoZSBvdXRwdXQhCmJha2VkX3Rlc3RfcG0gPC0gcmVjaXBlczo6YmFrZShwcmVwcGVkX3JlYywgbmV3X2RhdGEgPSB0ZXN0X3BtKQpnbGltcHNlKGJha2VkX3Rlc3RfcG0pCmBgYAojIyMjCgoKTm90aWNlIHRoYXQgb3VyIGBjaXR5X05vdC5pbi5hLmNpdHlgIHZhcmlhYmxlIHNlZW1zIHRvIGJlIE5BIHZhbHVlcy4gCldoeSBtaWdodCB0aGF0IGJlPwoKQWghIFBlcmhhcHMgaXQgaXMgYmVjYXVzZSBzb21lIG9mIG91ciBsZXZlbHMgd2VyZSBub3QgcHJldmlvdXNseSBzZWVuIGluIHRoZSB0cmFpbmluZyBzZXQhCgpMZXQncyB0YWtlIGEgbG9vayB1c2luZyB0aGUgW3NldCBvcGVyYXRpb25zXShodHRwczovL3d3dy5wcm9iYWJpbGl0eWNvdXJzZS5jb20vY2hhcHRlcjEvMV8yXzJfc2V0X29wZXJhdGlvbnMucGhwKXt0YXJnZXQ9Il9ibGFuayJ9IG9mIHRoZSBgZHBseXJgIHBhY2thZ2UuIApXZSBjYW4gdGFrZSBhIGxvb2sgYXQgY2l0aWVzIHRoYXQgd2VyZSBkaWZmZXJlbnQgYmV0d2VlbiB0aGUgdGVzdCBhbmQgdHJhaW5pbmcgc2V0LgoKYGBge3J9CnRyYWluY2l0aWVzIDwtIHRyYWluX3BtICU+JSBkaXN0aW5jdChjaXR5KQp0ZXN0Y2l0aWVzIDwtIHRlc3RfcG0gJT4lIGRpc3RpbmN0KGNpdHkpCgojZ2V0IHRoZSBudW1iZXIgb2YgY2l0aWVzIHRoYXQgd2VyZSBkaWZmZXJlbnQKZGltKGRwbHlyOjpzZXRkaWZmKHRyYWluY2l0aWVzLCB0ZXN0Y2l0aWVzKSkKCiNnZXQgdGhlIG51bWJlciBvZiBjaXRpZXMgdGhhdCBvdmVybGFwcGVkCmRpbShkcGx5cjo6aW50ZXJzZWN0KHRyYWluY2l0aWVzLCB0ZXN0Y2l0aWVzKSkKYGBgCgpJbmRlZWQsIHRoZXJlIGFyZSBsb3RzIG9mIGRpZmZlcmVudCBjaXRpZXMgaW4gb3VyIHRlc3QgZGF0YSB0aGF0IGFyZSBub3QgaW4gb3VyIHRyYWluaW5nIGRhdGEhCgoKU28sIGxldCBnbyBiYWNrIHRvIG91ciBgcG1gIGRhdGEgc2V0IGFuZCBtb2RpZnkgdGhlIGBjaXR5YCB2YXJpYWJsZSB0byBqdXN0IGJlIHZhbHVlcyBvZiBgaW4gYSBjaXR5YCBvciBgbm90IGluIGEgY2l0eWAgdXNpbmcgdGhlIGBjYXNlX3doZW4oKWAgZnVuY3Rpb24gb2YgYGRwbHlyYC4KVGhpcyBmdW5jdGlvbiBhbGxvd3MgeW91IHRvIHZlY3Rvcml6ZSBtdWx0aXBsZSBgaWZfZWxzZSgpYCBzdGF0ZW1lbnRzLgoKYGBge3J9CnBtICU+JQogIG11dGF0ZShjaXR5ID0gY2FzZV93aGVuKGNpdHkgPT0gIk5vdCBpbiBhIGNpdHkiIH4gIk5vdCBpbiBhIGNpdHkiLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNpdHkgIT0gIk5vdCBpbiBhIGNpdHkiIH4gIkluIGEgY2l0eSIpKQpgYGAKCkFsdGVybmF0aXZlbHkgeW91IGNvdWxkIGNyZWF0ZSBhIFtjdXN0b20gc3RlcCBmdW5jdGlvbl0oaHR0cHM6Ly9yZWNpcGVzLnRpZHltb2RlbHMub3JnL2FydGljbGVzL0N1c3RvbV9TdGVwcy5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9IHRvIGRvIHRoaXMgYW5kIGFkZCB0aGlzIHRvIHlvdXIgcmVjaXBlLCBidXQgdGhhdCBpcyBiZXlvbmQgdGhlIHNjb3BlIG9mIHRoaXMgY2FzZSBzdHVkeS4gCgpXZSB3aWxsIG5lZWQgdG8gcmVwZWF0IGFsbCB0aGUgc3RlcHMgKHNwbGl0dGluZyB0aGUgZGF0YSwgcHJlLXByb2Nlc3NpbmcsIGV0YykgYXMgdGhlIGxldmVscyBvZiBvdXIgdmFyaWFibGVzIGhhdmUgbm93IGNoYW5nZWQuIAoKV2hpbGUgd2UgYXJlIGRvaW5nIHRoaXMsIHdlIG1pZ2h0IGFsc28gaGF2ZSB0aGlzIGlzc3VlIGZvciBgY291bnR5YC4gCgpUaGUgYGNvdW50eWAgdmFyaWFibGVzIGFwcGVhcnMgdG8gZ2V0IGRyb3BwZWQgZHVlIHRvIGVpdGhlciBjb3JyZWxhdGlvbiBvciBuZWFyIHplcm8gdmFyaWFuY2UuIAoKSXQgaXMgbGlrZWx5IGR1ZSB0byBuZWFyIHplcm8gdmFyaWFuY2UgYmVjYXVzZSB0aGlzIGlzIHRoZSBtb3JlIGdyYW51bGFyIG9mIHRoZXNlIGdlb2dyYXBoaWMgY2F0ZWdvcmljYWwgdmFyaWFibGVzIGFuZCBsaWtlbHkgc3BhcnNlLgoKYGBge3J9CnBtICU8PiUKICBtdXRhdGUoY2l0eSA9IGNhc2Vfd2hlbihjaXR5ID09ICJOb3QgaW4gYSBjaXR5IiB+ICJOb3QgaW4gYSBjaXR5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICBjaXR5ICE9ICJOb3QgaW4gYSBjaXR5IiB+ICJJbiBhIGNpdHkiKSkKCnNldC5zZWVkKDEyMzQpICMgc2FtZSBzZWVkIGFzIGJlZm9yZQpwbV9zcGxpdCA8LXJzYW1wbGU6OmluaXRpYWxfc3BsaXQoZGF0YSA9IHBtLCBwcm9wID0gMi8zKQpwbV9zcGxpdAogdHJhaW5fcG0gPC1yc2FtcGxlOjp0cmFpbmluZyhwbV9zcGxpdCkKIHRlc3RfcG0gPC1yc2FtcGxlOjp0ZXN0aW5nKHBtX3NwbGl0KQpgYGAKCgojIyMjIHsucmVjYWxsX2NvZGVfcXVlc3Rpb25fYmxvY2t9CjxiPjx1PiBRdWVzdGlvbiBPcHBvcnR1bml0eSA8L3U+PC9iPgoKU2VlIGlmIHlvdSBjYW4gY29tZSB1cCB3aXRoIHRoZSBjb2RlIGZvciB0aGUgbmV3IHJlY2lwZS4KCiMjIyMKCioqKgoKPGRldGFpbHM+IDxzdW1tYXJ5PiBDbGljayBoZXJlIHRvIHJldmVhbCB0aGUgY29kZSBmb3IgdGhlIG5ldyByZWNpcGUuIDwvc3VtbWFyeT4KCgpgYGB7cn0Kbm92ZWxfcmVjIDwtcmVjaXBlKHRyYWluX3BtKSAlPiUKICAgIHVwZGF0ZV9yb2xlKGV2ZXJ5dGhpbmcoKSwgbmV3X3JvbGUgPSAicHJlZGljdG9yIikgJT4lCiAgICB1cGRhdGVfcm9sZSh2YWx1ZSwgbmV3X3JvbGUgPSAib3V0Y29tZSIpICU+JQogICAgdXBkYXRlX3JvbGUoaWQsIG5ld19yb2xlID0gImlkIHZhcmlhYmxlIikgJT4lCiAgICB1cGRhdGVfcm9sZSgiZmlwcyIsIG5ld19yb2xlID0gImNvdW50eSBpZCIpICU+JQogICAgc3RlcF9kdW1teShzdGF0ZSwgY291bnR5LCBjaXR5LCB6Y3RhLCBvbmVfaG90ID0gVFJVRSkgJT4lCiAgICBzdGVwX2NvcnIoYWxsX251bWVyaWMoKSkgJT4lCiAgICBzdGVwX256dihhbGxfbnVtZXJpYygpKSAKYGBgCjwvZGV0YWlscz4KKioqCgpgYGB7cn0Kbm92ZWxfcmVjCmBgYAoKCgpOb3cgbGV0J3MgcmV0cmFpbiBvdXIgdHJhaW5pbmcgZGF0YSBhbmQgdHJ5IGJha2luZyBvdXIgdGVzdCBkYXRhLgoKCgojIyMjIHsucmVjYWxsX2NvZGVfcXVlc3Rpb25fYmxvY2t9CjxiPjx1PiBRdWVzdGlvbiBPcHBvcnR1bml0eSA8L3U+PC9iPgoKRG8geW91IHJlY2FsbCBob3cgdG8gcHJlLXByb2Nlc3MgYW5kIGV4dHJhY3QgdGhlIHByZS1wcm9jZXNzZWQgdHJhaW5pbmcgZGF0YT8KCiMjIyMKCioqKgoKPGRldGFpbHM+IDxzdW1tYXJ5PiBDbGljayBoZXJlIHRvIHJldmVhbCB0aGUgYW5zd2VyLiA8L3N1bW1hcnk+CgpgYGB7cn0KcHJlcHBlZF9yZWMgPC0gcHJlcChub3ZlbF9yZWMsIHZlcmJvc2UgPSBUUlVFLCByZXRhaW4gPSBUUlVFKQpqdWljZWRfdHJhaW4gPC0ganVpY2UocHJlcHBlZF9yZWMpCmBgYAo8L2RldGFpbHM+IAoqKioKCgojIyMjIHsuc2Nyb2xsYWJsZSB9CmBgYHtyfQojIFNjcm9sbCB0aHJvdWdoIHRoZSBvdXRwdXQhCmdsaW1wc2UoanVpY2VkX3RyYWluKQpgYGAKCiMjIyMKCkFuZCBub3csIGxldCdzIHRyeSBiYWtpbmcgb3VyIHRlc3Qgc2V0IHRvIHNlZSBpZiB3ZSBzdGlsbCBoYXZlIGBOQWAgdmFsdWVzLgoKIyMjIyB7LnNjcm9sbGFibGUgfQoKYGBge3J9CiMgU2Nyb2xsIHRocm91Z2ggdGhlIG91dHB1dCEKYmFrZWRfdGVzdF9wbSA8LSByZWNpcGVzOjpiYWtlKHByZXBwZWRfcmVjLCBuZXdfZGF0YSA9IHRlc3RfcG0pCgpnbGltcHNlKGJha2VkX3Rlc3RfcG0pCmBgYAoKIyMjIwoKR3JlYXQgbm93IHdlIG5vIGxvbmdlciBoYXZlIGBOQWAgdmFsdWVzISA6KQoKKipOb3RlKio6IGlmIHlvdSB1c2UgdGhlIHNraXAgb3B0aW9uIGZvciBzb21lIG9mIHRoZSBwcmUtcHJvY2Vzc2luZyBzdGVwcywgYmUgY2FyZWZ1bC4gCmBqdWljZSgpYCB3aWxsIHNob3cgYWxsIG9mIHRoZSByZXN1bHRzIGlnbm9yaW5nIGBza2lwID0gVFJVRWAuIApgYmFrZSgpYCB3aWxsIG5vdCBuZWNlc3NhcmlseSBjb25kdWN0IHRoZXNlIHN0ZXBzIG9uIHRoZSBuZXcgZGF0YS4KCgojIyBTcGVjaWZ5aW5nIHRoZSBtb2RlbAoKU28gZmFyIHdlIGhhdmUgdXNlZCB0aGUgcGFja2FnZXMgYHJzYW1wbGVgIHRvIHNwbGl0IHRoZSBkYXRhIGFuZCBgcmVjaXBlc2AgdG8gYXNzaWduIHZhcmlhYmxlIHR5cGVzLCBhbmQgdG8gc3BlY2lmeSBhbmQgcHJlcCBvdXIgcHJlLXByb2Nlc3NpbmcgKGFzIHdlbGwgYXMgdG8gb3B0aW9uYWxseSBleHRyYWN0IHRoZSBwcmUtcHJvY2Vzc2VkIGRhdGEpLgoKV2Ugd2lsbCBub3cgdXNlIHRoZSBgcGFyc25pcGAgcGFja2FnZSAod2hpY2ggaXMgc2ltaWxhciB0byB0aGUgcHJldmlvdXMgYGNhcmV0YCBwYWNrYWdlIC0gYW5kIGhlbmNlIHdoeSBpdCBpcyBuYW1lZCBhZnRlciB0aGUgdmVnZXRhYmxlKSB0byBzcGVjaWZ5IG91ciBtb2RlbC4KClRoZXJlIGFyZSBmb3VyIHRoaW5ncyB3ZSBuZWVkIHRvIGRlZmluZSBhYm91dCBvdXIgbW9kZWw6ICAKCjEuIFRoZSAqKnR5cGUqKiBvZiBtb2RlbCAodXNpbmcgc3BlY2lmaWMgZnVuY3Rpb25zIGluIHBhcnNuaXAgbGlrZSBgcmFuZF9mb3Jlc3QoKWAsIGBsb2dpc3RpY19yZWcoKWAgZXRjLikgIAoyLiBUaGUgcGFja2FnZSBvciAqKmVuZ2luZSoqIHRoYXQgd2Ugd2lsbCB1c2UgdG8gaW1wbGVtZW50IHRoZSB0eXBlIG9mIG1vZGVsIHNlbGVjdGVkICh1c2luZyB0aGUgYHNldF9lbmdpbmUoKWAgZnVuY3Rpb24pIAozLiBUaGUgKiptb2RlKiogb2YgbGVhcm5pbmcgLSBjbGFzc2lmaWNhdGlvbiBvciByZWdyZXNzaW9uICh1c2luZyB0aGUgYHNldF9tb2RlKClgIGZ1bmN0aW9uKSAKNC4gQW55ICoqYXJndW1lbnRzKiogbmVjZXNzYXJ5IGZvciB0aGUgbW9kZWwvcGFja2FnZSBzZWxlY3RlZCAodXNpbmcgdGhlIGBzZXRfYXJncygpYGZ1bmN0aW9uIC0gIGZvciBleGFtcGxlIHRoZSBgbXRyeSA9YCBhcmd1bWVudCBmb3IgcmFuZG9tIGZvcmVzdCB3aGljaCBpcyB0aGUgbnVtYmVyIG9mIHZhcmlhYmxlcyB0byBiZSB1c2VkIGFzIG9wdGlvbnMgZm9yIHNwbGl0dGluZyBhdCBlYWNoIHRyZWUgbm9kZSkKCkxldCdzIHdhbGsgdGhyb3VnaCB0aGVzZSBzdGVwcyBvbmUgYnkgb25lLiAKRm9yIG91ciBjYXNlLCB3ZSBhcmUgZ29pbmcgdG8gc3RhcnQgb3VyIGFuYWx5c2lzIHdpdGggYSBsaW5lYXIgcmVncmVzc2lvbiBidXQgd2Ugd2lsbCBkZW1vbnN0cmF0ZSBob3cgd2UgY2FuIHRyeSBkaWZmZXJlbnQgbW9kZWxzLgoKVGhlIGZpcnN0IHN0ZXAgaXMgdG8gZGVmaW5lIHdoYXQgdHlwZSBvZiBtb2RlbCB3ZSB3b3VsZCBsaWtlIHRvIHVzZS4gClNlZSBbaGVyZV0oaHR0cHM6Ly93d3cudGlkeW1vZGVscy5vcmcvZmluZC9wYXJzbmlwLyl7dGFyZ2V0PSJfYmxhbmsifSBmb3IgbW9kZWxpbmcgb3B0aW9ucyBpbiBgcGFyc25pcGAuCgoKYGBge3J9ClBNX21vZGVsIDwtIHBhcnNuaXA6OmxpbmVhcl9yZWcoKSAjIFBNIHdhcyB1c2VkIGluIHRoZSBuYW1lIGZvciBwYXJ0aWN1bGF0ZSBtYXR0ZXIKUE1fbW9kZWwKYGBgCgpPSy4gU28gZmFyLCBhbGwgd2UgaGF2ZSBkZWZpbmVkIGlzIHRoYXQgd2Ugd2FudCB0byB1c2UgYSBsaW5lYXIgcmVncmVzc2lvbi4uLiAgCkxldCdzIHRlbGwgYHBhcnNuaXBgIG1vcmUgYWJvdXQgd2hhdCB3ZSB3YW50LgoKV2Ugd291bGQgbGlrZSB0byB1c2UgdGhlIFtvcmRpbmFyeSBsZWFzdCBzcXVhcmVzXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9PcmRpbmFyeV9sZWFzdF9zcXVhcmVzKSBtZXRob2QgdG8gZml0IG91ciBsaW5lYXIgcmVncmVzc2lvbi4gClNvIHdlIHdpbGwgdGVsbCBgcGFyc25pcGAgdGhhdCB3ZSB3YW50IHRvIHVzZSB0aGUgYGxtYCBwYWNrYWdlIHRvIGltcGxlbWVudCBvdXIgbGluZWFyIHJlZ3Jlc3Npb24gKHRoZXJlIGFyZSBtYW55IG9wdGlvbnMgYWN0dWFsbHkgc3VjaCBhcyBbYHJzdGFuYF0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL3JzdGFuL3ZpZ25ldHRlcy9yc3Rhbi5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9ICBbYGdsbW5ldGBdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9nbG1uZXQvaW5kZXguaHRtbCl7dGFyZ2V0PSJfYmxhbmsifSwgW2BrZXJhc2BdKGh0dHBzOi8va2VyYXMucnN0dWRpby5jb20vKXt0YXJnZXQ9Il9ibGFuayJ9LCBhbmQgW2BzcGFya2x5cmBdKGh0dHBzOi8vdGhlcmluc3BhcmsuY29tL3N0YXJ0aW5nLmh0bWwjc3RhcnRpbmctc3BhcmtseXItaGVsbG8td29ybGQpe3RhcmdldD0iX2JsYW5rIn0pLiBTZWUgW2hlcmVdKGh0dHBzOi8vcGFyc25pcC50aWR5bW9kZWxzLm9yZy9yZWZlcmVuY2UvbGluZWFyX3JlZy5odG1sKSBmb3IgYSBkZXNjcmlwdGlvbiBvZiB0aGUgZGlmZmVyZW5jZXMgYW5kIHVzaW5nIHRoZXNlIGRpZmZlcmVudCBlbmdpbmVzIHdpdGggYHBhcnNuaXBgLgoKV2Ugd2lsbCBkbyBzbyBieSB1c2luZyB0aGUgYHNldF9lbmdpbmUoKWAgZnVuY3Rpb24gb2YgdGhlIGBwYXJzbmlwYCBwYWNrYWdlLgoKYGBge3J9CmxtX1BNX21vZGVsIDwtIAogIFBNX21vZGVsICAlPiUKICBwYXJzbmlwOjpzZXRfZW5naW5lKCJsbSIpCgpsbV9QTV9tb2RlbApgYGAKCkluIHNvbWUgY2FzZXMgc29tZSBwYWNrYWdlcyBjYW4gZG8gZWl0aGVyIGNsYXNzaWZpY2F0aW9uIG9yIHByZWRpY3Rpb24sIHNvIGl0IGlzIGEgZ29vZCBpZGVhIHRvIHNwZWNpZnkgd2hpY2ggbW9kZSB5b3UgaW50ZW5kIHRvIHBlcmZvcm0uIApIZXJlLCB3ZSBhaW0gdG8gcHJlZGljdCB0aGUgYWlyIHBvbGx1dGlvbi4gCllvdSBjYW4gZG8gdGhpcyB3aXRoIHRoZSBgc2V0X21vZGUoKWAgZnVuY3Rpb24gb2YgdGhlIGBwYXJzbmlwYCBwYWNrYWdlLCBieSB1c2luZyBlaXRoZXIgYHNldF9tb2RlKCJjbGFzc2lmaWNhdGlvbiIpYCBvciBgc2V0X21vZGUoInJlZ3Jlc3Npb24iKWAuCgpgYGB7cn0KbG1fUE1fbW9kZWwgPC0gCiAgUE1fbW9kZWwgICU+JQogIHBhcnNuaXA6OnNldF9lbmdpbmUoImxtIikgJT4lCiAgc2V0X21vZGUoInJlZ3Jlc3Npb24iKQoKbG1fUE1fbW9kZWwKYGBgCgojIyBGaXR0aW5nIHRoZSBtb2RlbAoKV2UgY2FuICB1c2UgdGhlIGBwYXJzbmlwYCBwYWNrYWdlIHdpdGggYSBuZXdlciBwYWNrYWdlIGNhbGxlZCBgd29ya2Zsb3dzYCB0byBmaXQgb3VyIG1vZGVsLiAKClRoZSBgd29ya2Zsb3dzYCBwYWNrYWdlIGFsbG93cyB1cyB0byBrZWVwIHRyYWNrIG9mIGJvdGggb3VyIHByZS1wcm9jZXNzaW5nIHN0ZXBzIGFuZCBvdXIgbW9kZWwgc3BlY2lmaWNhdGlvbi4gSXQgYWxzbyBhbGxvd3MgdXMgdG8gaW1wbGVtZW50IGZhbmNpZXIgb3B0aW1pemF0aW9ucyBpbiBhbiBhdXRvbWF0ZWQgd2F5IGFuZCBpdCBjYW4gYWxzbyBoYW5kbGUgcG9zdC1wcm9jZXNzaW5nIG9wZXJhdGlvbnMuIAoKCldlIGJlZ2luIGJ5IGNyZWF0aW5nIGEgd29ya2Zsb3cgdXNpbmcgdGhlIGB3b3JrZmxvdygpYCBmdW5jdGlvbiBpbiB0aGUgYHdvcmtmbG93c2AgcGFja2FnZS4gCgpOZXh0LCB3ZSB1c2UgYGFkZF9yZWNpcGUoKWAgKG91ciBwcmUtcHJvY2Vzc2luZyBzcGVjaWZpY2F0aW9ucykgYW5kIHdlIGFkZCBvdXIgbW9kZWwgd2l0aCB0aGUgYGFkZF9tb2RlbCgpYCBmdW5jdGlvbiAtLSBib3RoIGZ1bmN0aW9ucyBmcm9tIHRoZSBgd29ya2Zsb3dzYCBwYWNrYWdlLgoKKipOb3RlKio6IFdlIGRvIG5vdCBuZWVkIHRvIGFjdHVhbGx5IGBwcmVwKClgIG91ciByZWNpcGUgYmVmb3JlIHVzaW5nIHdvcmtmbG93cyEKCklmIHlvdSByZWNhbGwgYG5vdmVsX3JlY2AgaXMgdGhlIHJlY2lwZSB3ZSBwcmV2aW91c2x5IGNyZWF0ZWQgd2l0aCB0aGUgYHJlY2lwZXNgIHBhY2thZ2UgYW5kIGBsbV9QTV9tb2RlbGAgd2FzIGNyZWF0ZWQgd2hlbiB3ZSBzcGVjaWZpZWQgb3VyIG1vZGVsIHdpdGggdGhlIGBwYXJzbmlwYCBwYWNrYWdlLgpIZXJlLCB3ZSBjb21iaW5lIGV2ZXJ5dGhpbmcgdG9nZXRoZXIgaW50byBhIGB3b3JrZmxvdygpYC4gCgpgYGB7cn0KUE1fd2Zsb3cgPC13b3JrZmxvd3M6OndvcmtmbG93KCkgJT4lCiAgICAgICAgICAgd29ya2Zsb3dzOjphZGRfcmVjaXBlKG5vdmVsX3JlYykgJT4lCiAgICAgICAgICAgd29ya2Zsb3dzOjphZGRfbW9kZWwobG1fUE1fbW9kZWwpClBNX3dmbG93CmBgYAoKQWgsIG5pY2UuIApOb3RpY2UgaG93IGl0IHRlbGxzIHVzIGFib3V0IGJvdGggb3VyIHByZS1wcm9jZXNzaW5nIHN0ZXBzIGFuZCBvdXIgbW9kZWwgc3BlY2lmaWNhdGlvbnMuCgpOZXh0LCB3ZSAicHJlcGFyZSB0aGUgcmVjaXBlIiAob3IgZXN0aW1hdGUgdGhlIHBhcmFtZXRlcnMpIGFuZCBmaXQgdGhlIG1vZGVsIHRvIG91ciB0cmFpbmluZyBkYXRhIGFsbCBhdCBvbmNlLiAKUHJpbnRpbmcgdGhlIG91dHB1dCwgd2UgY2FuIHNlZSB0aGUgY29lZmZpY2llbnRzIG9mIHRoZSBtb2RlbC4KCmBgYHtyfQpQTV93Zmxvd19maXQgPC0gcGFyc25pcDo6Zml0KFBNX3dmbG93LCBkYXRhID0gdHJhaW5fcG0pClBNX3dmbG93X2ZpdApgYGAKCgo8ZGV0YWlscz48c3VtbWFyeT4gQ2xpY2sgaGVyZSB0byBzZWUgdGhlIHN0ZXBzIHRoYXQgdGhlIGB3b3JrZmxvd3NgIHBhY2thZ2UgcGVyZm9ybXMgdGhhdCB1c2VkIHRvIGJlIHJlcXVpcmVkIDwvc3VtbWFyeT4KCkFWT0NBRE86dGhpcyBzZWN0aW9uIGZlZWxzIGxpa2UgaXQgc2hvdWxkIGVpdGhlciBoYXZlIG1vcmUgZXhwbGFuYXRpb24gb3IganVzdCBkZWxldGVkLiBUbyBtZSBpdCBmZWVscyBjb25mdXNpbmcgYmVjYXVzZSBpdCBmZWVscyBsaWtlIHdlIGFyZSBzaG93aW5nIGEgY29tcGxldGVseSBhbHRlcm5hdGl2ZSBwYXRoIHdpdGhvdXQgYW4gZXhwbGFuYXRpb24gd2h5IHlvdSBtaWdodCB3YW50IHRvIGRvPyBvciB3aGVuIHlvdSB3b3VsZCB3YW50IHRvIGRvIHRoaXM/IAoKYXZvY2FkbyByZXNwb25zZS13aGF0IGRvIHlvdSB0aGluayBvZiBob3cgSSB0aXRsZWQgdGhpcyBzZWN0aW9uIC0gaWYgeW91IHN0aWxsIGRvbid0IGxpa2UgaXQgZmVlbCBmcmVlIHRvIGRlbGV0ZQoKUHJldmlvdXNseSB0aGUgcHJvY2Vzc2VkIHRyYWluaW5nIGRhdGEgKGBqdWljZWRfdHJhaW5gKSBhcyBvcHBvc2VkIHRvIHRoZSByYXcgdHJhaW5pbmcgZGF0YSB3b3VsZCBiZSByZXF1aXJlZCB0byBmaXQgdGhlIG1vZGVsLgoKSW4gdGhpcyBjYXNlLCB3ZSB3b3VsZCBhY3R1YWxseSBhbHNvIG5lZWRlZCB0byB3cml0ZSB5b3VyIG1vZGVsIGFnYWluISAKUmVjYWxsIHRoYXQgYGlkYCBhbmQgYGZpcHNgIGFyZSBJRCB2YXJpYWJsZXMgYW5kIHRoYXQgYHZhbHVlc2AgaXMgb3VyIG91dGNvbWUgb2YgaW50ZXJlc3QgKHRoZSBhaXIgcG9sbHV0aW9uIG1lYXN1cmUgYXQgZWFjaCBtb25pdG9yKS4gSXQgaXMgbmljZSB0aGF0IGB3b3JrZmxvd3NgIGtlZXBzIHRyYWNrIG9mIHRoaXMhCgpgYGB7cn0KanVpY2VkX3RyYWluX3JlYWR5IDwtIGp1aWNlZF90cmFpbiAlPiUgCiAgc2VsZWN0KC1pZCwgLWZpcHMpCgpQTV9maXQgPC0gbG1fUE1fbW9kZWwgJT4lIAogIHBhcnNuaXA6OmZpdCh2YWx1ZSB+LiwgZGF0YSA9IGp1aWNlZF90cmFpbl9yZWFkeSkKYGBgCgo8L2RldGFpbHM+CgojIyBBc3Nlc3NpbmcgdGhlIG1vZGVsIGZpdAoKQWZ0ZXIgd2UgZml0IG91ciBtb2RlbCwgd2UgY2FuIHVzZSB0aGUgYGJyb29tYCBwYWNrYWdlIHRvIGxvb2sgYXQgdGhlIG91dHB1dCBmcm9tIHRoZSBmaXR0ZWQgbW9kZWwgaW4gYW4gZWFzeS90aWR5LiAgIAoKVGhlIGB0aWR5KClgIGZ1bmN0aW9uIHJldHVybnMgYSB0aWR5IGRhdGEgZnJhbWUgd2l0aCBjb2VmZmljaWVudHMgZnJvbSB0aGUgbW9kZWwgKG9uZSByb3cgcGVyIGNvZWZmaWNpZW50KS4KCk1hbnkgb3RoZXIgYGJyb29tYCBmdW5jdGlvbnMgY3VycmVudGx5IG9ubHkgd29yayB3aXRoIGBwYXJzbmlwYCBvYmplY3RzLCBub3QgcmF3IGB3b3JrZmxvd3NgIG9iamVjdHMuIAoKSG93ZXZlciwgd2UgY2FuIHVzZSB0aGUgYHRpZHlgIGZ1bmN0aW9uIGlmIHdlIGZpcnN0IHVzZSB0aGUgYHB1bGxfd29ya2Zsb3dfZml0KClgIGZ1bmN0aW9uLgoKYGBge3J9CndmbG93b3V0cHV0IDwtIFBNX3dmbG93X2ZpdCAlPiUgCiAgcHVsbF93b3JrZmxvd19maXQoKSAlPiUgCiAgYnJvb206OnRpZHkoKSAKYGBgCgoKYGBge3J9CndmbG93b3V0cHV0CmBgYAoKV2UgaGF2ZSBmaXQgb3VyIG1vZGVsIG9uIG91ciB0cmFpbmluZyBkYXRhLCB3aGljaCBtZWFucyB3ZSBoYXZlIGNyZWF0ZWQgYSBtb2RlbCB0byBwcmVkaWN0IHZhbHVlcyBvZiBhaXIgcG9sbHV0aW9uIGJhc2VkIG9uIHRoZSBwcmVkaWN0b3JzIHRoYXQgd2UgaGF2ZSBpbmNsdWRlZC4gWWF5IQoKT25lIGxhc3QgdGhpbmcgYmVmb3JlIHdlIGxlYXZlIHRoaXMgc2VjdGlvbi4gCldlIG9mdGVuIGFyZSBpbnRlcmVzdGVkIGluIGdldHRpbmcgYSBzZW5zZSBvZiB3aGljaCB2YXJpYWJsZXMgYXJlIHRoZSBtb3N0IGltcG9ydGFudCBpbiBvdXIgbW9kZWwuIApXZSBjYW4gZXhwbG9yZSB0aGUgdmFyaWFibGUgaW1wb3J0YW5jZSB1c2luZyB0aGUgYHZpcCgpYCBmdW5jdGlvbiBvZiB0aGUgYHZpcGAgcGFja2FnZS4gClRoaXMgZnVuY3Rpb24gY3JlYXRlIGEgYmFyIHBsb3Qgb2YgdmFyaWFibGUgaW1wb3J0YW5jZSBzY29yZXMgZm9yIGVhY2ggcHJlZGljdG9yIHZhcmlhYmxlIChvciBmZWF0dXJlKSBpbiBhIG1vZGVsLiAKVGhlIGJhciBwbG90IGlzIG9yZGVyZWQgYnkgaW1wb3J0YW5jZSAoaGlnaGVzdCB0byBzbWFsbGVzdCkuIAoKCk5vdGljZSBhZ2FpbiB0aGF0IHdlIG5lZWQgdG8gdXNlIHRoZSBgcHVsbF93b3JrZmxvd19maXQoKWAgZnVuY3Rpb24uCgpMZXQncyB0YWtlIGEgbG9vayBhdCB0aGUgdG9wIDEwIGNvbnRyaWJ1dGluZyB2YXJpYWJsZXM6CgpgYGB7cn0KUE1fd2Zsb3dfZml0ICU+JSAKICBwdWxsX3dvcmtmbG93X2ZpdCgpICU+JSAKICB2aXAobnVtX2ZlYXR1cmVzID0gMTApCmBgYAoKVGhlIHN0YXRlIGluIHdoaWNoIHRoZSBtb25pdG9yIHdhcyBsb2NhdGVkIGFuZCB0aGUgQ01BUSBtb2RlbCBhbmQgdGhlIGFvZCBzYXRlbGxpdGUgaW5mb3JtYXRpb24gYXBwZWFyIHRvIGJlIHRoZSBtb3N0IGltcG9ydGFudCBmb3IgcHJlZGljdGluZyB0aGUgYWlyIHBvbGx1dGlvbiBhdCBhIGdpdmVuIG1vbml0b3IuCgojIyBNb2RlbCBwZXJmb3JtYW5jZQoKSW4gdGhpcyBuZXh0IHNlY3Rpb24sIG91ciBnb2FsIGlzIHRvIGFzc2VzcyB0aGUgb3ZlcmFsbCBtb2RlbCBwZXJmb3JtYW5jZS4gClRoZSB3YXkgd2UgZG8gdGhpcyBpcyB0byBjb21wYXJlIHRoZSBzaW1pbGFyaXR5IGJldHdlZW4gdGhlIHByZWRpY3RlZCBlc3RpbWF0ZXMgb2YgdGhlIG91dGNvbWUgdmFyaWFibGUgcHJvZHVjZWQgYnkgdGhlIG1vZGVsIGFuZCB0aGUgdHJ1ZSBvdXRjb21lIHZhcmlhYmxlIHZhbHVlcy4gCgpJZiB5b3UgcmVjYWxsIHRoZSBbV2hhdCBpcyBtYWNoaW5lIGxlYXJuaW5nP10oI3doYXRpc21sKSBzZWN0aW9uLCB3ZSBzaG93ZWQgaG93IHRvIHRoaW5rIGFib3V0IG1hY2hpbmUgbGVhcm5pbmcgKE1MKSBhcyBhbiBvcHRpbWl6YXRpb24gcHJvYmxlbSB0aGF0IHRyaWVzIHRvIG1pbmltaXplIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIG91ciBwcmVkaWN0ZWQgb3V0Y29tZSAkXGhhdHtZfSA9IGYoWCkkIGFuZCBhY3R1YWwgb3V0Y29tZSAkWSQgdXNpbmcgb3VyIGZlYXR1cmVzIChvciBwcmVkaWN0b3IgdmFyaWFibGVzKSAkWCQgYXMgaW5wdXQgdG8gYSBmdW5jdGlvbiAkZiQgdGhhdCB3ZSB3YW50IHRvIGVzdGltYXRlLiAKCiQkZChZIC0gXGhhdHtZfSkkJAoKQXMgb3VyIGdvYWwgaW4gdGhpcyBzZWN0aW9uIGlzIHRvIGFzc2VzcyBvdmVyYWxsIG1vZGVsIHBlcmZvcm1hbmNlLCB3ZSB3aWxsIG5vdyB0YWxrIGFib3V0IGRpZmZlcmVudCBkaXN0YW5jZSBtZXRyaWNzIHRoYXQgeW91IGNhbiB1c2UuIAoKRmlyc3QsIGxldCdzIHB1bGwgb3V0IG91ciBwcmVkaWN0ZWQgb3V0Y29tZSB2YWx1ZXMgJFxoYXR7WX0gPSBmKFgpJCBmcm9tIHRoZSBtb2RlbHMgd2UgZml0ICh1c2luZyBkaWZmZXJlbnQgYXBwcm9hY2hlcykuIAoKCmBgYHtyfQp3Zl9maXQgPC0gUE1fd2Zsb3dfZml0ICU+JSAKICBwdWxsX3dvcmtmbG93X2ZpdCgpCgp3Zl9maXR0ZWRfdmFsdWVzIDwtIGZpdHRlZCh3Zl9maXRbWyJmaXQiXV0pCmhlYWQod2ZfZml0dGVkX3ZhbHVlcykKYGBgCgpBbHRlcm5hdGl2ZWx5LCB3ZSBjYW4gZ2V0IHRoZSBmaXR0ZWQgdmFsdWVzIHVzaW5nIHRoZSBgYXVnbWVudCgpYCBmdW5jdGlvbiBvZiB0aGUgYGJyb29tYCBwYWNrYWdlIHVzaW5nIHRoZSBvdXRwdXQgZnJvbSBgd29ya2Zsb3dzYDogCgpgYGB7cn0Kd2ZfZml0dGVkX3ZhbHVlcyA8LSAKICBicm9vbTo6YXVnbWVudCh3Zl9maXRbWyJmaXQiXV0sIGRhdGEgPSBqdWljZWRfdHJhaW4pICU+JSAKICBzZWxlY3QodmFsdWUsIC5maXR0ZWQ6LnN0ZC5yZXNpZCkKCmhlYWQod2ZfZml0dGVkX3ZhbHVlcykKCmBgYAoKTm90ZSB0aGF0IGJlY3Vhc2Ugd2UgdXNlIHRoZSBhY3R1YWwgd29ya2Zsb3cgaGVyZSwgd2UgY2FuIChhbmQgYWN0dWFsbHkgbmVlZCB0bykgdXNlIHRoZSByYXcgZGF0YSBpbnN0ZWFkIG9mIHRoZSBwcmUtcHJvY2Vzc2VkIGRhdGEuCgpgYGB7cn0KdmFsdWVzX3ByZWRfdHJhaW4gPC0gCiAgcHJlZGljdChQTV93Zmxvd19maXQsIHRyYWluX3BtKSAlPiUgCiAgYmluZF9jb2xzKHRyYWluX3BtICU+JSBzZWxlY3QodmFsdWUsIGZpcHMsIGNvdW50eSwgaWQpKSAKCnZhbHVlc19wcmVkX3RyYWluCgpgYGAKCiMjIyBWaXN1YWxpemluZyBtb2RlbCBwZXJmb3JtYW5jZQoKTm93LCB3ZSBjYW4gY29tcGFyZSB0aGUgcHJlZGljdGVkIG91dGNvbWUgdmFsdWVzIChvciBmaXR0ZWQgdmFsdWVzKSAkXGhhdHtZfSQgdG8gdGhlIGFjdHVhbCBvdXRjb21lIHZhbHVlcyAkWSQgdGhhdCB3ZSBvYnNlcnZlZDogCgpgYGB7cn0Kd2ZfZml0dGVkX3ZhbHVlcyAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gIHZhbHVlLCB5ID0gLmZpdHRlZCkpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgeGxhYigiYWN0dWFsIG91dGNvbWUgdmFsdWVzIikgKyAKICB5bGFiKCJwcmVkaWN0ZWQgb3V0Y29tZSB2YWx1ZXMiKQpgYGAKCk9LLCBzbyBvdXIgcmFuZ2Ugb2YgdGhlIHByZWRpY3RlZCBvdXRjb21lIHZhbHVlcyBhcHBlYXJzIHRvIGJlIHNtYWxsZXIgdGhhbiB0aGUgcmVhbCB2YWx1ZXMuIApXZSBjb3VsZCBwcm9iYWJseSBkbyBhIGJpdCBiZXR0ZXIuCgojIyMgUXVhbnRpZnlpbmcgbW9kZWwgcGVyZm9ybWFuY2UgCgpOZXh0LCBsZXQncyB1c2UgZGlmZmVyZW50IGRpc3RhbmNlIGZ1bmN0aW9ucyAkZChcY2RvdCkkIHRvIGFzc2VzcyBob3cgZmFyIG9mZiBvdXIgcHJlZGljdGVkIG91dGNvbWUgJFxoYXR7WX0gPSBmKFgpJCBhbmQgYWN0dWFsIG91dGNvbWUgJFkkIHZhbHVlcyBhcmUgZnJvbSBlYWNoIG90aGVyOiAKCiQkZChZIC0gXGhhdHtZfSkkJAoKQXMgbWVudGlvbmVkLCB0aGVyZSBhcmUgZW50aXJlIHNjaG9sYXJseSBmaWVsZHMgb2YgcmVzZWFyY2ggZGVkaWNhdGVkIHRvIGlkZW50aWZ5aW5nIGRpZmZlcmVudCBkaXN0YW5jZSBtZXRyaWNzICRkKFxjZG90KSQgZm9yIG1hY2hpbmUgbGVhcm5pbmcgYXBwbGljYXRpb25zLiAKSG93ZXZlciwgd2hlbiBwZXJmb3JtaW5nIHByZWRpY3Rpb24gd2l0aCBhIGNvbnRpbnVvdXMgb3V0Y29tZSAkWSQsIGEgZmV3IG9mIHRoZSBtb3N0bHkgY29tbW9ubHkgdXNlZCBkaXN0YW5jZSBtZXRyaWNzIGFyZTogCgoxLiBtZWFuIGFic29sdXRlIGVycm9yIChgbWFlYCkgIAoKJCRNQUUgPSBcZnJhY3tcc3VtX3tpPTF9XntufXsofFxoYXR7eV90fS0geV90fCl9XjJ9e259JCQKCgoyLiBSIHNxdWFyZWQgZXJyb3IgKGByc3FgKSAtLSB0aGlzIGlzIGFsc28ga25vd24gYXMgdGhlIGNvZWZmaWNpZW50IG9mIGRldGVybWluYXRpb24gd2hpY2ggaXMgdGhlIHNxdWFyZWQgY29ycmVsYXRpb24gYmV0d2VlbiB0cnV0aCBhbmQgZXN0aW1hdGUKClRoaXMgaXMgY2FsY3VsYXRlZCBhbmQgMSBtaW51cyB0aGUgZnJhY3Rpb24gb2YgdGhlIHJlc2lkdWFsIHN1bSBvZiBzcXVhcmVzICgkU1NfcmVzJCkgYnkgdGhlIHRvdGFsIHN1bSBvZiBzcXVhcmVzICgkU1NfdG90JCkKCgokJFJTUSA9IFJeMiA9IDEgLSBcZnJhY3tTU3Jlc317U1N0b3R9JCQKCiQkU1Nfe3RvdH0gPSBcc3VtX3tpPTF9XntufXsoeV9pLSBcYmFye3l9KX1eMiQkClRoZSB0b3RhbCBzdW0gb2Ygc3F1YXJlcyBpcyBwcm9wb3J0aW9uYWwgdG8gdGhlIHZhcmlhbmNlIG9mIHRoZSBkYXRhLiBJdCBpcyBjYWxjdWxhdGVkIGFzIHRoZSBzdW0gb2YgZWFjaCAgdHJ1ZSB2YWx1ZSBmcm9tIHRoZSBtZWFuIHRydWUgdmFsdWUgKCRcYmFye3l9JCkuCgokJFNTX3tyZXN9ID0gXHN1bV97aT0xfV57bn17KHlfaS0gXGhhdHt5X2l9KX1eMiQkCgpUaGUgc3VtIG9mIHNxdWFyZXMgb2YgcmVzaWR1YWxzIGlzIGNhbGN1bGF0ZWQgYXMgdGhlIHN1bSBvZiBlYWNoIHByZWRpY3RlZCB2YWx1ZSAoJFxoYXR7eV9pfSQgb3Igc29tZXRpbWVzICRmX2kkKSBmcm9tIHRoZSB0cnVlIHZhbHVlICgkeV9pJCkuIAoKCjMuIFtyb290IG1lYW4gc3F1YXJlZCBlcnJvcl0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvUm9vdC1tZWFuLXNxdWFyZV9kZXZpYXRpb24pe3RhcmdldD0iX2JsYW5rIn0gKGBybXNlYCkgICAKCiQkUk1TRSA9IFxzcXJ0e1xmcmFje1xzdW1fe2k9MX1ee259eyhcaGF0e3lfdH0tIHlfdCl9XjJ9e259fSQkCgoKCgpPbmUgd2F5IHRvIGNhbGN1bGF0ZSB0aGVzZSBtZXRyaWNzIHdpdGhpbiB0aGUgYHRpZHltb2RlbHNgIGZyYW1ld29yayBpcyB0byB1c2UgdGhlIGB5YXJkc3RpY2tgIHBhY2thZ2UgdXNpbmcgdGhlIGBtZXRyaWNzKClgIGZ1bmN0aW9uLiAKCmBgYHtyfQp5YXJkc3RpY2s6Om1ldHJpY3Mod2ZfZml0dGVkX3ZhbHVlcywgCiAgICAgICAgICAgICAgICAgICB0cnV0aCA9IHZhbHVlLCBlc3RpbWF0ZSA9IC5maXR0ZWQpCmBgYAoKQWx0ZXJuYXRpdmVseSBpZiB5b3Ugb25seSB3YW50ZWQgb25lIG1ldHJpYyB5b3UgY291bGQgdXNlIHRoZSBgbWFlKClgLCBgcnNxKClgLCBvciBgcm1zZSgpYCBmdW5jdGlvbnMsIHJlc3BlY3RpdmVseS4gCgpgYGB7cn0KeWFyZHN0aWNrOjptYWUod2ZfZml0dGVkX3ZhbHVlcywgCiAgICAgICAgICAgICAgIHRydXRoID0gdmFsdWUsIGVzdGltYXRlID0gLmZpdHRlZCkKYGBgCgojIyBDcm9zcyB2YWxpZGF0aW9uCgpVbnRpbCBub3cgd2UgaGF2ZSB1c2VkIGV2ZXJ5dGhpbmcgaW4gb3VyICJ0cmFpbmluZyIgZGF0YXNldCAoYW5kIGhhdmUgbm90IHRvdWNoZWQgdGhlICJ0ZXN0aW5nIiBkYXRhc2V0KSBmcm9tIHRoZSBgcnNhbXBsZWAgcGFja2FnZSB0byBidWlsZCBvdXIgbWFjaGluZSBsZWFybmluZyAoTUwpIG1vZGVsICRcaGF0e1l9ID0gZihYKSQgKG9yIHRvIGVzdGltYXRlICRmJCB1c2luZyB0aGUgZmVhdHVyZXMgb3IgcHJlZGljdG9yIHZhcmlhYmxlICRYJCkuIAoKSGVyZSwgd2UgdGFrZSBtb3ZlIHRoaXMgYmV5b25kIHRoZSBzaW1wbGUgc3BsaXQgaW50byB0cmFpbmluZyBhbmQgdGVzdGluZyBkYXRhIHNldHMuIApXZSB3aWxsIGFnYWluIHVzZSB0aGUgYHJzYW1wbGVgIHBhY2thZ2UgYWdhaW4gaW4gb3JkZXIgdG8gZnVydGhlciBpbXBsZW1lbnQgd2hhdCBhcmUgY2FsbGVkIFtjcm9zcyB2YWxpZGF0aW9uXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Dcm9zcy12YWxpZGF0aW9uXyhzdGF0aXN0aWNzKSl7dGFyZ2V0PSJfYmxhbmsifSB0ZWNobmlxdWVzLiBUaGlzIGlzIGFsc28gY2FsbGVkICoqcmUtc2FtcGxpbmcqKiBvciAqKnJlcGFydGlvbmluZyoqLiAgCgoqKk5vdGUqKjogd2UgYXJlIG5vdCBhY3R1YWxseSBnZXR0aW5nIG5ldyBzYW1wbGVzIGZyb20gdGhlIHVuZGVybHlpbmcgZGlzdHJpYnV0aW9uIHNvIHRoZSB0ZXJtIHJlLXNhbXBsaW5nIGlzIGEgYml0IG9mIGEgbWlzbm9tZXIuCgpbQ3Jvc3MgdmFsaWRhdGlvbl0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ3Jvc3MtdmFsaWRhdGlvbl8oc3RhdGlzdGljcykpe3RhcmdldD0iX2JsYW5rIn0gc3BsaXRzIG91ciB0cmFpbmluZyBkYXRhIGludG8gbXVsdGlwbGUgdHJhaW5pbmcgZGF0YSBzZXRzIHRvIGFsbG93IGZvciBhIGRlZXBlciBhc3Nlc3NtZW50IG9mIHRoZSBhY2N1cmFjeSBvZiB0aGUgbW9kZWwuCgpIZXJlIGlzIGEgdmlzdWFsaXphdGlvbiBvZiB0aGUgY29uY2VwdCBmb3IgY3Jvc3MgdmFsaWRhdGlvbi9yZXNhbXBsaW5nL3JlcGFydGl0aW9uaW5nIGZyb20gW01heCBLdWhuXShodHRwczovL3Jlc291cmNlcy5yc3R1ZGlvLmNvbS9hdXRob3JzL21heC1rdWhuKXt0YXJnZXQ9Il9ibGFuayJ9OgoKYGBge3IsIGVjaG89RkFMU0UsIG91dC53aWR0aD0iODAwcHgifQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbWciLCJyZXNhbXBsaW5nLnBuZyIpKQpgYGAKClRlY2huaWNhbGx5IGNyZWF0aW5nIG91ciB0ZXN0aW5nIGFuZCB0cmFpbmluZyBzZXQgb3V0IG9mIG91ciBvcmlnaW5hbCB0cmFpbmluZyBkYXRhIGlzIHNvbWV0aW1lcyBjb25zaWRlcmVkIGEgZm9ybSBvZiBbY3Jvc3MgdmFsaWRhdGlvbl0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ3Jvc3MtdmFsaWRhdGlvbl8oc3RhdGlzdGljcykpe3RhcmdldD0iX2JsYW5rIn0sIGNhbGxlZCB0aGUgaG9sZG91dCBtZXRob2QuIApUaGUgcmVhc29uIHdlIGRvIHRoaXMgaXQgc28gd2UgY2FuIGdldCBhIGJldHRlciBzZW5zZSBvZiB0aGUgYWNjdXJhY3kgb2Ygb3VyIG1vZGVsIHVzaW5nIGRhdGEgdGhhdCB3ZSBkaWQgbm90IHRyYWluIGl0IG9uLiAKCkhvd2V2ZXIsIHdlIGNhbiBhY3R1YWxseSBkbyBhIGJldHRlciBqb2Igb2Ygb3B0aW1pemluZyBvdXIgbW9kZWwgZm9yIGFjY3VyYWN5IGlmIHdlIGFsc28gcGVyZm9ybSBhbm90aGVyIHR5cGUgb2YgW2Nyb3NzIHZhbGlkYXRpb25dKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Nyb3NzLXZhbGlkYXRpb25fKHN0YXRpc3RpY3MpKXt0YXJnZXQ9Il9ibGFuayJ9IG9uIHRoZSBuZXdseSBkZWZpbmVkIHRyYWluaW5nIHNldCB0aGF0IHdlIGp1c3QgY3JlYXRlZC4gClRoZXJlIGFyZSBtYW55IFtjcm9zcyB2YWxpZGF0aW9uXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Dcm9zcy12YWxpZGF0aW9uXyhzdGF0aXN0aWNzKSl7dGFyZ2V0PSJfYmxhbmsifSBtZXRob2RzIGFuZCBtb3N0IGNhbiBiZSBlYXNpbHkgaW1wbGVtZW50ZWQgdXNpbmcgYHJzYW1wbGVgIHBhY2thZ2UuIApIZXJlLCB3ZSB3aWxsIHVzZSBhIHZlcnkgcG9wdWxhciBtZXRob2QgY2FsbGVkIGVpdGhlciBbay1mb2xkIG9yIHYtZm9sZCBjcm9zcyB2YWxpZGF0aW9uXShodHRwczovL21hY2hpbmVsZWFybmluZ21hc3RlcnkuY29tL2stZm9sZC1jcm9zcy12YWxpZGF0aW9uLyl7dGFyZ2V0PSJfYmxhbmsifS4gCgpUaGlzIG1ldGhvZCBpbnZvbHZlcyBlc3NlbnRpYWxseSBwcmVmb3JtaW5nIHRoZSBob2xkIG91dCBtZXRob2QgaXRlcmF0aXZlbHkgd2l0aCB0aGUgdHJhaW5pbmcgZGF0YS4gCgpGaXJzdCwgdGhlIHRyYWluaW5nIHNldCBpcyBkaXZpZGVkIGludG8gJHYkIChvciBvZnRlbiBjYWxsZWQgY2FsbGVkICRrJCkgZXF1YWxseSBzaXplZCBzbWFsbGVyIHBpZWNlcy4gCgpOZXh0LCB0aGUgbW9kZWwgaXMgdHJhaW5lZCBvbiB0aGUgbW9kZWwgb24gJHYkLTEgc3Vic2V0cyBvZiB0aGUgZGF0YSBpdGVyYXRpdmVseSAocmVtb3ZpbmcgYSBkaWZmZXJlbnQgJHYkIHVudGlsIGFsbCBwb3NzaWJsZSAkdiQtMSBzZXRzIGhhdmUgYmVlbiBldmFsdWF0ZWQpIHRvIGdldCBhIHNlbnNlIG9mIHRoZSBwZXJmb3JtYW5jZSBvZiB0aGUgbW9kZWwuIApUaGlzIGlzIHJlYWxseSB1c2VmdWwgZm9yIGZpbmUgdHVuaW5nIHNwZWNpZmljIGFzcGVjdHMgb2YgdGhlIG1vZGVsIGluIGEgcHJvY2VzcyBjYWxsZWQgbW9kZWwgdHVuaW5nLCB3aGljaCB3ZSB3aWxsIGxlYXJuIGFib3V0IGluIHRoZSBuZXh0IHNlY3Rpb24uIAoKSGVyZSBpcyBhIHZpc3VhbGl6YXRpb24gb2YgaG93IHRoZSBmb2xkcyBhcmUgY3JlYXRlZDoKCmBgYHtyLCBlY2hvPUZBTFNFLCBvdXQud2lkdGg9IjgwMHB4In0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1nIiwgInZmb2xkLnBuZyIpKQpgYGAKCioqTm90ZSoqOiBQZW9wbGUgdHlwaWNhbGx5IGlnbm9yZSBzcGF0aWFsIGRlcGVuZGVuY2Ugd2l0aCBjcm9zcyB2YWxpZGF0aW9uIG9mIGFpciBwb2xsdXRpb24gbW9uaXRvcmluZyBkYXRhIGluIHRoZSBhaXIgcG9sbHV0aW9uIGZpZWxkLCBzbyB3ZSB3aWxsIGRvIHRoZSBzYW1lLiAgSG93ZXZlciwgaXQgbWlnaHQgbWFrZSBzZW5zZSB0byBsZWF2ZSBvdXQgYmxvY2tzIG9mIG1vbml0b3JzIHJhdGhlciB0aGFuICByYW5kb20gaW5kaXZpZHVhbCBtb25pdG9ycyB0byBoZWxwIGFjY291bnQgZm9yIHNvbWUgc3BhdGlhbCBkZXBlbmRlbmNlLgoKIyMjIENyZWF0aW5nIHRoZSAkdiQtZm9sZHMgdXNpbmcgYHJzYW1wbGVgCgpUaGUgW2B2Zm9sZF9jdigpYF0oaHR0cHM6Ly90aWR5bW9kZWxzLmdpdGh1Yi5pby9yc2FtcGxlL3JlZmVyZW5jZS92Zm9sZF9jdi5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9IGZ1bmN0aW9uIG9mIHRoZSBgcnNhbXBsZWAgcGFja2FnZSBjYW4gYmUgdXNlZCB0byBwYXJzZSB0aGUgdHJhaW5pbmcgZGF0YSBpbnRvIGZvbGRzIGZvciAkdiQtZm9sZCBjcm9zcyB2YWxpZGF0aW9uLgoKLSBUaGUgYHZgIGFyZ3VtZW50IHNwZWNpZmllcyB0aGUgbnVtYmVyIG9mIGZvbGRzIHRvIGNyZWF0ZS4KLSBUaGUgYHJlcGVhdHNgIGFyZ3VtZW50IHNwZWNpZmllcyBpZiBhbnkgc2FtcGxlcyBzaG91bGQgYmUgcmVwZWF0ZWQgYWNyb3NzIGZvbGRzIC0gZGVmYXVsdCBpcyBgRkFMU0VgCi0gVGhlIGBzdHJhdGFgIGFyZ3VtZW50IHNwZWNpZmllcyBhIHZhcmlhYmxlIHRvIHN0cmF0aWZ5IHNhbXBsZXMgYWNyb3NzIGZvbGRzIC0ganVzdCBsaWtlIGluIGBpbml0aWFsX3NwbGl0KClgLgoKQWdhaW4sIGJlY2F1c2UgdGhlc2UgYXJlIGNyZWF0ZWQgYXQgcmFuZG9tLCB3ZSBuZWVkIHRvIHVzZSB0aGUgYmFzZSBgc2V0LnNlZWQoKWAgZnVuY3Rpb24gaW4gb3JkZXIgdG8gb2J0YWluIHRoZSBzYW1lIHJlc3VsdHMgZWFjaCB0aW1lIHdlIGtuaXQgdGhpcyBkb2N1bWVudC4gCkdlbmVyYWxseSBzcGVha2luZyB1c2luZyAxMCBmb2xkcyBpcyBnb29kIHByYWN0aWNlLCBidXQgdGhpcyBkZXBlbmRzIG9uIHRoZSB2YXJpYWJpbGl0eSB3aXRoaW4geW91ciBkYXRhLiAKV2UgYXJlIGdvaW5nIHRvIHVzZSA0IGZvciB0aGUgc2FrZSBvZiBleHBlZGllbmN5LiAKCmBgYHtyfQpzZXQuc2VlZCgxMjM0KQp2Zm9sZF9wbSA8LSByc2FtcGxlOjp2Zm9sZF9jdihkYXRhID0gdHJhaW5fcG0sIHYgPSA0KQp2Zm9sZF9wbQpwdWxsKHZmb2xkX3BtLCBzcGxpdHMpCmBgYAoKTm93IHdlIGNhbiBzZWUgdGhhdCB3ZSBoYXZlIGNyZWF0ZWQgNCBmb2xkcyBvZiB0aGUgZGF0YSBhbmQgd2UgY2FuIHNlZSBob3cgbWFueSB2YWx1ZXMgd2VyZSBzZXQgYXNpZGUgZm9yIHRlc3RpbmcgKGNhbGxlZCBhc3Nlc3NpbmcgZm9yIGNyb3NzIHZhbGlkYXRpb24gc2V0cykgYW5kIHRyYWluaW5nIChjYWxsZWQgYW5hbHlzaXMgZm9yIGNyb3NzIHZhbGlkYXRpb24gc2V0cykgd2l0aGluIGVhY2ggZm9sZC4KCk9uY2UgdGhlIGZvbGRzIGFyZSBjcmVhdGVkIHRoZXkgY2FuIGJlIHVzZWQgdG8gZXZhbHVhdGUgcGVyZm9ybWFuY2UgYnkgZml0dGluZyB0aGUgbW9kZWwgdG8gZWFjaCBvZiB0aGUgcmUtc2FtcGxlcyB0aGF0IHdlIGNyZWF0ZWQ6CgpgYGB7ciwgZWNobz1GQUxTRSwgb3V0LndpZHRoPSI4MDBweCJ9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltZyIsICJjcm9zc192YWxpZGF0aW9uLnBuZyIpKQpgYGAKCiMjIyBBc3Nlc3NpbmcgbW9kZWwgcGVyZm9ybWFuY2Ugb24gJHYkLWZvbGRzIHVzaW5nIGB0dW5lYAoKV2UgY2FuIGZpdCB0aGUgbW9kZWwgdG8gb3VyIGNyb3NzIHZhbGlkYXRpb24gZm9sZHMgdXNpbmcgdGhlIGBmaXRfcmVzYW1wbGVzKClgIGZ1bmN0aW9uIG9mIHRoZSBgdHVuZWAgcGFja2FnZSwgYnkgc3BlY2lmeWluZyBvdXIgYHdvcmtmbG93YCBvYmplY3QgYW5kIHRoZSBjcm9zcyB2YWxpZGF0aW9uIGZvbGQgb2JqZWN0IHdlIGp1c3QgY3JlYXRlZC4gClNlZSBbaGVyZV0oaHR0cHM6Ly90aWR5bW9kZWxzLmdpdGh1Yi5pby90dW5lL3JlZmVyZW5jZS9maXRfcmVzYW1wbGVzLmh0bWwpe3RhcmdldD0iX2JsYW5rIn0gZm9yIG1vcmUgaW5mb3JtYXRpb24uCgoKYGBge3J9CnJlc2FtcGxlX2ZpdCA8LSB0dW5lOjpmaXRfcmVzYW1wbGVzKFBNX3dmbG93LCB2Zm9sZF9wbSkKYGBgCgpXZSBjYW4gbm93IHRha2UgYSBsb29rIGF0IHZhcmlvdXMgcGVyZm9ybWFuY2UgbWV0cmljcyBiYXNlZCBvbiB0aGUgZml0IG9mIG91ciBjcm9zcyB2YWxpZGF0aW9uICJyZXNhbXBsZXMiLiAKVG8gZG8gdGhpcyB3ZSB3aWxsIHVzZSB0aGUgYHNob3dfYmVzdCgpYCBmdW5jdGlvbiBvZiB0aGUgYHR1bmVgIHBhY2thZ2UuCgpgYGB7cn0KdHVuZTo6c2hvd19iZXN0KHJlc2FtcGxlX2ZpdCwgbWV0cmljID0gInJtc2UiKQpgYGAKCkhlcmUgd2UgY2FuIHNlZSB0aGUgbWVhbiBgUk1TRWAgdmFsdWUgYWNyb3NzIGFsbCBmb3VyIGZvbGRzLiBUaGUgZnVuY3Rpb24gaXMgY2FsbGVkIGBzaG93X2Jlc3QoKWAgYmVjYXVzZSBpdCBpcyBhbHNvIHVzZWQgZm9yIG1vZGVsIHR1bmluZyBhbmQgaXQgd2lsbCBzaG93IHRoZSBwYXJhbWV0ZXIgY29tYmluYXRpb24gd2l0aCB0aGUgYmVzdCBwZXJmb3JtYW5jZSwgd2Ugd2lsbCBkaXNjdXNzIHRoaXMgbW9yZSBsYXRlciBpbiB0aGUgY2FzZSBzdHVkeS4KCgojICoqRGF0YSBBbmFseXNpcyoqCioqKgoKSW4gdGhlIHByZXZpb3VzIHNlY3Rpb24sIHdlIGRlbW9uc3RyYXRlZCBob3cgdG8gYnVpbGQgYSBtYWNoaW5lIGxlYXJuaW5nIG1vZGVsIChzcGVjaWZpY2FsbHkgYSBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbCkgdG8gcHJlZGljdCBhaXIgcG9sbHV0aW9uIHdpdGggdGhlIGB0aWR5bW9kZWxzYCBmcmFtZXdvcmsuIAoKSW4gdGhlIG5leHQgZmV3IHNlY3Rpb24sIHdlIHdpbGwgZGVtb25zdHJhdGUgYW5vdGhlciBtYWNoaW5lIGxlYXJuaW5nIG1vZGVsLiAKCgojIyBSYW5kb20gRm9yZXN0CgpOb3csIHdlIGFyZSBnb2luZyB0byBwcmVkaWN0IG91ciBvdXRjb21lIHZhcmlhYmxlIChhaXIgcG9sbHV0aW9uKSB1c2luZyBhIGRlY2lzaW9uIHRyZWUgbWV0aG9kIGNhbGxlZCBbcmFuZG9tIGZvcmVzdF0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvUmFuZG9tX2ZvcmVzdCl7dGFyZ2V0PSJfYmxhbmsifS4KCkEgW2RlY2lzaW9uIHRyZWVdKGh0dHBzOi8vbWVkaXVtLmNvbS9ncmV5YXRvbS9kZWNpc2lvbi10cmVlcy1hLXNpbXBsZS13YXktdG8tdmlzdWFsaXplLWEtZGVjaXNpb24tZGM1MDZhNDAzYWViKXt0YXJnZXQ9Il9ibGFuayJ9IGlzIGEgdG9vbCB0byBwYXJ0aXRpb24gZGF0YSBvciBhbnl0aGluZyByZWFsbHksIGJhc2VkIG9uIGEgc2VyaWVzIG9mIHNlcXVlbnRpYWwgKG9mdGVuIGJpbmFyeSkgZGVjaXNpb25zLCB3aGVyZSB0aGUgZGVjaXNpb25zIGFyZSBjaG9zZW4gYmFzZWQgb24gdGhlaXIgYWJpbGl0eSB0byBvcHRpbWFsbHkgc3BsaXQgdGhlIGRhdGEuCgpIZXJlIHlvdSBjYW4gc2VlIGEgc2ltcGxlIGV4YW1wbGU6CgpgYGB7ciwgZWNobyA9IEZBTFNFfQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiaHR0cHM6Ly9taXJvLm1lZGl1bS5jb20vbWF4LzEwMDAvMSpMTW9KbVhDc1FsY2lHVEV5b1NOMzlnLmpwZWciKQpgYGAKCiMjIyMjIFtbc291cmNlXV0oaHR0cHM6Ly90b3dhcmRzZGF0YXNjaWVuY2UuY29tL3VuZGVyc3RhbmRpbmctcmFuZG9tLWZvcmVzdC01ODM4MWUwNjAyZDIpe3RhcmdldD0iX2JsYW5rIn0KCkluIHRoZSBjYXNlIG9mIFtyYW5kb20gZm9yZXN0XShodHRwczovL3Rvd2FyZHNkYXRhc2NpZW5jZS5jb20vZGVjaXNpb24tdHJlZS1lbnNlbWJsZXMtYmFnZ2luZy1hbmQtYm9vc3RpbmctMjY2YThiYTYwZmQ5KXt0YXJnZXQ9Il9ibGFuayJ9LCBtdWx0aXBsZSBkZWNpc2lvbiB0cmVlcyBhcmUgY3JlYXRlZCAtIGhlbmNlIHRoZSBuYW1lIGZvcmVzdCwgYW5kIGVhY2ggdHJlZSBpcyBidWlsdCB1c2luZyBhIHJhbmRvbSBzdWJzZXQgb2YgdGhlIHRyYWluaW5nIGRhdGEgKHdpdGggcmVwbGFjZW1lbnQpIC0gaGVuY2UgdGhlIGZ1bGwgbmFtZSByYW5kb20gZm9yZXN0LiBUaGlzIHJhbmRvbSBhc3BlY3QgaGVscHMgdG8ga2VlcCB0aGUgYWxnb3JpdGhtIGZyb20gb3ZlcmZpdHRpbmcgdGhlIGRhdGEuCgpUaGUgbWVhbiBvZiB0aGUgcHJlZGljdGlvbnMgZnJvbSBlYWNoIG9mIHRoZSB0cmVlcyBpcyB1c2VkIGluIHRoZSBmaW5hbCBvdXRwdXQuCgpgYGB7ciwgZWNobyA9IEZBTFNFfQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiaHR0cHM6Ly9taXJvLm1lZGl1bS5jb20vbWF4LzE0MDAvMCpmX3FRUEZwZG9mV0dMUXFjLnBuZyIpCmBgYAoKCkluIG91ciBjYXNlLCB3ZSBhcmUgZ29pbmcgdG8gdXNlIHRoZSByYW5kb20gZm9yZXN0IG1ldGhvZCBvZiB0aGUgdGhlIGByYW5kb21Gb3Jlc3RgIHBhY2thZ2UuIAoKVGhpcyBwYWNrYWdlIGlzIGN1cnJlbnRseSBub3QgY29tcGF0aWJsZSB3aXRoIGNhdGVnb3JpY2FsIHZhcmlhYmxlcyB0aGF0IGhhdmUgbW9yZSB0aGFuIDUzIGxldmVscy4gU2VlIFtoZXJlXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvcmFuZG9tRm9yZXN0L05FV1MpIGZvciB0aGUgZG9jdW1lbnRhdGlvbiBhYm91dCB3aGVuIHRoaXMgd2FzIHVwZGF0ZWQgZnJvbSAyNSBsZXZlbHMuIFRodXMgd2Ugd2lsbCB0byByZW1vdmUgdGhlIGB6Y3RhYCAgYW5kIGBjb3VudHlgIHZhcmlhYmxlcy4KCk5vdGUgdGhhdCB0aGUgYHN0ZXBfbm92ZWwoKWAgZnVuY3Rpb24gaXMgbmVjZXNzYXJ5IGhlcmUgZm9yIGBzdGF0ZWAgdG8gZ2V0IGFsbCBjcm9zcyB2YWxpZGF0aW9uIGZvbGRzIHRvIHdvcmssIGJlY2F1c2UgdGhlcmUgd2lsbCBiZSBkaWZmZXJlbnQgbGV2ZWxzIGluY2x1ZGVkIGluIGVhY2ggZm9sZCB0ZXN0IGFuZCB0cmFpbmluZyBzZXRzLCB0aHVzIHRoZXJlIGFyZSBuZXcgbGV2ZWxzIGZvciBzb21lIG9mIHRoZSB0ZXN0IHNldHMgd2hpY2ggd2lsbCByZXN1bHQgaW4gYW4gZXJyb3IuICAKCkFjY29yZGluZyB0byB0aGUgW2RvY3VtZW50YXRpb25dKGh0dHBzOi8vd3d3LnJkb2N1bWVudGF0aW9uLm9yZy9wYWNrYWdlcy9yZWNpcGVzL3ZlcnNpb25zLzAuMS4xMy90b3BpY3Mvc3RlcF9ub3ZlbCkgZm9yIHRoZSBgcmVjaXBlc2AgcGFja2FnZToKCj4gc3RlcF9ub3ZlbCBjcmVhdGVzIGEgc3BlY2lmaWNhdGlvbiBvZiBhIHJlY2lwZSBzdGVwIHRoYXQgd2lsbCBhc3NpZ24gYSBwcmV2aW91c2x5IHVuc2VlbiBmYWN0b3IgbGV2ZWwgdG8gYSBuZXcgdmFsdWUuCgpgYGB7cn0KUkZfcmVjIDwtIHJlY2lwZSh0cmFpbl9wbSkgJT4lCiAgICB1cGRhdGVfcm9sZShldmVyeXRoaW5nKCksIG5ld19yb2xlID0gInByZWRpY3RvciIpJT4lCiAgICB1cGRhdGVfcm9sZSh2YWx1ZSwgbmV3X3JvbGUgPSAib3V0Y29tZSIpJT4lCiAgICB1cGRhdGVfcm9sZShpZCwgbmV3X3JvbGUgPSAiaWQgdmFyaWFibGUiKSAlPiUKICAgIHVwZGF0ZV9yb2xlKCJmaXBzIiwgbmV3X3JvbGUgPSAiY291bnR5IGlkIikgJT4lCiAgICBzdGVwX25vdmVsKCJzdGF0ZSIpICU+JQogICAgc3RlcF9zdHJpbmcyZmFjdG9yKCJzdGF0ZSIsICJjb3VudHkiLCAiY2l0eSIpICU+JQogICAgc3RlcF9ybSgiY291bnR5IikgJT4lCiAgICBzdGVwX3JtKCJ6Y3RhIikgJT4lCiAgICBzdGVwX2NvcnIoYWxsX251bWVyaWMoKSklPiUKICAgIHN0ZXBfbnp2KGFsbF9udW1lcmljKCkpCmBgYAoKVGhlIGByYW5kX2ZvcmVzdCgpYCBmdW5jdGlvbiBvZiB0aGUgYHBhcnNuaXBgIHBhY2thZ2UgaGFzIHRocmVlIGltcG9ydGFudCBhcmd1bWVudHMgdGhhdCBhY3QgYXMgYW4gaW50ZXJmYWNlIGZvciB0aGUgZGlmZmVyZW50IHBvc3NpYmxlIGVuZ2luZXMgdG8gcGVyZm9ybSBhIHJhbmRvbSBmb3Jlc3QgYW5hbHlzaXM6CgoxLiBgbXRyeWAgLSBUaGUgbnVtYmVyIG9mIHByZWRpY3RvciB2YXJpYWJsZXMgKG9yIGZlYXR1cmVzKSB0aGF0IHdpbGwgYmUgcmFuZG9tbHkgc2FtcGxlZCBhdCBlYWNoIHNwbGl0IHdoZW4gY3JlYXRpbmcgdGhlIHRyZWUgbW9kZWxzLiBUaGUgZGVmYXVsdCBudW1iZXIgZm9yIHJlZ3Jlc3Npb24gYW5hbHlzZXMgaXMgdGhlIG51bWJlciBvZiBwcmVkaWN0b3JzIGRpdmlkZWQgYnkgMy4gCjIuIGBtaW5fbmAgLSBUaGUgbWluaW11bSBudW1iZXIgb2YgZGF0YSBwb2ludHMgaW4gYSBub2RlIHRoYXQgYXJlIHJlcXVpcmVkIGZvciB0aGUgbm9kZSB0byBiZSBzcGxpdCBmdXJ0aGVyLgozLiBgdHJlZXNgIC0gdGhlIG51bWJlciBvZiB0cmVlcyBpbiB0aGUgZW5zZW1ibGUKCldlIHdpbGwgc3RhcnQgYnkgdHJ5aW5nIGFuIGBtdHJ5YCB2YWx1ZSBvZiAxMCBhbmQgYSBgbWluX25gIHZhbHVlIG9mIDMuCgpOb3cgdGhhdCB3ZSBoYXZlIG91ciByZWNpcGUgKGBSRl9yZWNgKSwgbGV0J3Mgc3BlY2lmeSB0aGUgbW9kZWwgd2l0aCBgcmFuZF9mb3Jlc3QoKWAgZnJvbSBgcGFyc25pcGAgd2l0aCB0aGUgYG1vZGUgPSAicmVncmVzc2lvbiJgIGFyZ3VtZW50IHRvIHNwZWNpZnkgb3VyIG91dGNvbWUgdmFyaWFibGUgKGFpciBwb2xsdXRpb24pIGlzIGNvbnRpbnVvdXMuIAoKYGBge3J9ClBNdHJlZV9tb2RlbCA8LSAKICBwYXJzbmlwOjpyYW5kX2ZvcmVzdChtdHJ5ID0gMTAsIG1pbl9uID0gMywgCiAgICAgICAgICAgICAgICAgICAgICAgbW9kZSA9ICJyZWdyZXNzaW9uIikKUE10cmVlX21vZGVsCmBgYAoKTmV4dCwgd2Ugc2V0IHRoZSBlbmdpbmUgYW5kIG1vZGU6CgpOb3RlIHRoYXQgeW91IGNvdWxkIGFsc28gdXNlIHRoZSBgcmFuZ2VyYCBvciBgc3BhcmtgIHBhY2thZ2VzIGluc3RlYWQgb2YgYHJhbmRvbUZvcmVzdGAuCklmIHlvdSB3ZXJlIHRvIHVzZSB0aGUgYHJhbmdlcmAgcGFja2FnZSB0byBpbXBsZW1lbnQgdGhlIHJhbmRvbSBmb3Jlc3QgYW5hbHlzaXMgeW91IHdvdWxkIG5lZWQgdG8gc3BlY2lmeSBhbiBgaW1wb3J0YW5jZWAgYXJndW1lbnQgdG8gYmUgYWJsZSB0byBldmFsdWF0ZSBwcmVkaWN0b3IgaW1wb3J0YW5jZS4gIFRoZSBvcHRpb25zIGFyZSBgaW1wdXJpdHlgIG9yIGBwZXJtdXRhdGlvbmAuCgpUaGVzZSBvdGhlciBwYWNrYWdlcyBoYXZlIGRpZmZlcmVudCBhZHZhbnRhZ2VzIGFuZCBkaXNhZHZhbnRhZ2VzLSBmb3IgZXhhbXBsZSBgcmFuZ2VyYCBhbmQgYHNwYXJrYCBhcmUgbm90IGFzIGxpbWl0aW5nIGZvciB0aGUgbnVtYmVyIG9mIGNhdGVnb3JpZXMgZm9yIGNhdGVnb3JpY2FsIHZhcmlhYmxlcy4gRm9yIG1vcmUgaW5mb3JtYXRpb24gc2VlIHRoZWlyIGRvY3VtZW50YXRpb246IFtoZXJlXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvcmFuZ2VyL3Jhbmdlci5wZGYpIGZvciByYW5nZXIsIFtoZXJlXShodHRwOi8vc3BhcmsuYXBhY2hlLm9yZy9kb2NzL2xhdGVzdC9tbGxpYi1lbnNlbWJsZXMuaHRtbCNyYW5kb20tZm9yZXN0cykgZm9yIGBzcGFya2AsIGFuZCBbaGVyZV0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL3JhbmRvbUZvcmVzdC9yYW5kb21Gb3Jlc3QucGRmKSBmb3IgYHJhbmRvbUZvcmVzdGAuCgpTZWUgW2hlcmVdKGh0dHBzOi8vcGFyc25pcC50aWR5bW9kZWxzLm9yZy9yZWZlcmVuY2UvcmFuZF9mb3Jlc3QuaHRtbCkgZm9yIG1vcmUgZG9jdW1lbnRhdGlvbiBhYm91dCBpbXBsZW1lbnRpbmcgdGhlc2UgZW5naW5lIG9wdGlvbnMgd2l0aCB0aWR5bW9kZWxzLiBOb3RlIHRoYXQgdGhlcmUgYXJlIGFsc28gW290aGVyXShodHRwczovL3d3dy5saW5rZWRpbi5jb20vcHVsc2UvZGlmZmVyZW50LXJhbmRvbS1mb3Jlc3QtcGFja2FnZXMtci1tYWRodXItbW9kaS8pIFIgcGFja2FnZXMgZm9yIGltcGxlbWVudGluZyByYW5kb20gZm9yZXN0IGFsZ29yaXRobXMsIGJ1dCB0aGVzZSB0aHJlZSBwYWNrYWdlcyAoYHJhbmdlcmAsIGBzcGFya2AsIGFuZCBgcmFuZG9tRm9yZXN0YCkgYXJlIGN1cnJlbnRseSBjb21wYXRpYmxlIHdpdGggYHRpZHltb2RlbHNgLgoKYGBge3J9CgpSRl9QTV9tb2RlbCA8LSAKICBQTXRyZWVfbW9kZWwgJT4lCiAgc2V0X2VuZ2luZSgicmFuZG9tRm9yZXN0IikgJT4lCiAgc2V0X21vZGUoInJlZ3Jlc3Npb24iKQoKUkZfUE1fbW9kZWwKYGBgCgpUaGVuLCB3ZSBwdXQgdGhpcyBhbGwgdG9nZXRoZXIgaW50byBhIGB3b3JrZmxvd2A6IAoKIyMjIyB7LnJlY2FsbF9jb2RlX3F1ZXN0aW9uX2Jsb2NrfQo8Yj48dT4gUXVlc3Rpb24gT3Bwb3J0dW5pdHkgPC91PjwvYj4KClNlZSBpZiB5b3UgY2FuIGNvbWUgdXAgd2l0aCB0aGUgY29kZSB0byBkbyB0aGlzLgoKIyMjIwoKKioqCjxkZXRhaWxzPiA8c3VtbWFyeT4gQ2xpY2sgaGVyZSB0byByZXZlYWwgdGhlIGFuc3dlci4gPC9zdW1tYXJ5PgoKYGBge3J9ClJGX3dmbG93IDwtIHdvcmtmbG93czo6d29ya2Zsb3coKSAlPiUKICAgICAgICAgICAgd29ya2Zsb3dzOjphZGRfcmVjaXBlKFJGX3JlYykgJT4lCiAgICAgICAgICAgIHdvcmtmbG93czo6YWRkX21vZGVsKFJGX1BNX21vZGVsKQoKYGBgCjwvZGV0YWlscz4gCioqKgoKYGBge3J9ClJGX3dmbG93CmBgYAoKCkZpbmFsbHksIHdlIGZpdCB0aGUgZGF0YSB0byB0aGUgbW9kZWw6CiMjIyMgey5yZWNhbGxfY29kZV9xdWVzdGlvbl9ibG9ja30KPGI+PHU+IFF1ZXN0aW9uIE9wcG9ydHVuaXR5IDwvdT48L2I+CgpEbyB5b3UgcmVjYWxsIGhvdyB0byBkbyB0aGlzPwoKIyMjIwoKKioqCjxkZXRhaWxzPiA8c3VtbWFyeT4gQ2xpY2sgaGVyZSB0byByZXZlYWwgdGhlIGFuc3dlci4gPC9zdW1tYXJ5PgoKYGBge3J9ClJGX3dmbG93X2ZpdCA8LSBwYXJzbmlwOjpmaXQoUkZfd2Zsb3csIGRhdGEgPSB0cmFpbl9wbSkKYGBgCjwvZGV0YWlscz4gCioqKgoKYGBge3J9ClJGX3dmbG93X2ZpdApgYGAKCgpMZXQncyB0YWtlIGEgbG9vayBhdCB0aGUgdG9wIDEwIGNvbnRyaWJ1dGluZyB2YXJpYWJsZXM6CgoKIyMjIyB7LnJlY2FsbF9jb2RlX3F1ZXN0aW9uX2Jsb2NrfQo8Yj48dT4gUXVlc3Rpb24gT3Bwb3J0dW5pdHkgPC91PjwvYj4KClNlZSBpZiB5b3UgY2FuIHJlY2FsbCBob3cgdG8gZG8gdGhpcy4KCiMjIyMKCmBgYHtyLCBlY2hvID0gRkFMU0V9ClJGX3dmbG93X2ZpdCAlPiUgCiAgcHVsbF93b3JrZmxvd19maXQoKSAlPiUgCiAgdmlwKG51bV9mZWF0dXJlcyA9IDEwKQoKYGBgCgoKKioqCjxkZXRhaWxzPiA8c3VtbWFyeT4gQ2xpY2sgaGVyZSB0byByZXZlYWwgdGhlIGFuc3dlci4gPC9zdW1tYXJ5PgoKYGBge3J9ClJGX3dmbG93X2ZpdCAlPiUgCiAgcHVsbF93b3JrZmxvd19maXQoKSAlPiUgCiAgdmlwKG51bV9mZWF0dXJlcyA9IDEwKQpgYGAKPC9kZXRhaWxzPgoqKioKCgpJbnRlcmVzdGluZyEgSW4gdGhlIHByZXZpb3VzIG1vZGVsIHRoZSBDTUFRIHZhbHVlcyBhbmQgdGhlIHN0YXRlIHdoZXJlIHRoZSBtb25pdG9yIHdhcyBsb2NhdGVkIHdlcmUgYWxzbyB0aGUgdG9wIHR3byBtb3N0IGltcG9ydGFudCwgaG93ZXZlciBwcmVkaWN0b3JzIGFib3V0IGVkdWNhdGlvbiBsZXZlbHMgb2YgdGhlIGNvbW11bml0aWVzIHdoZXJlIHRoZSBtb25pdG9yIHdhcyBsb2NhdGVkIHdhcyBhbW9uZyB0aGUgdG9wIG1vc3QgaW1wb3J0YW50LiBOb3cgd2Ugc2VlIHRoYXQgcG9wdWxhdGlvbiBkZW5zaXR5IGFuZCBwcm94aW1pdHkgdG8gc291cmNlcyBvZiBlbWlzc2lvbnMgYW5kIHJvYWRzIGFyZSBhbW9uZyB0aGUgdG9wIHRlbi4KCgpOb3cgbGV0J3MgdGFrZSBhIGxvb2sgYXQgbW9kZWwgcGVyZm9ybWFuY2UgYnkgZml0dGluZyB0aGUgZGF0YSB1c2luZyBjcm9zcyB2YWxpZGF0aW9uOgoKIyMjIyB7LnJlY2FsbF9jb2RlX3F1ZXN0aW9uX2Jsb2NrfQo8Yj48dT4gUXVlc3Rpb24gT3Bwb3J0dW5pdHkgPC91PjwvYj4KClNlZSBpZiB5b3UgY2FuIHJlY2FsbCBob3cgdG8gZG8gdGhpcy4KCiMjIyMKCioqKgo8ZGV0YWlscz4gPHN1bW1hcnk+IENsaWNrIGhlcmUgdG8gcmV2ZWFsIHRoZSBhbnN3ZXIuIDwvc3VtbWFyeT4KCmBgYHtyLCBldmFsID0gRkFMU0V9CnNldC5zZWVkKDQ1NikKcmVzYW1wbGVfUkZfZml0IDwtIHR1bmU6OmZpdF9yZXNhbXBsZXMoUkZfd2Zsb3csIHZmb2xkX3BtKQpjb2xsZWN0X21ldHJpY3MocmVzYW1wbGVfUkZfZml0KQpgYGAKCjwvZGV0YWlscz4KKioqCgpgYGB7ciwgZWNobyA9IEZBTFNFfQpzZXQuc2VlZCg0NTYpCnJlc2FtcGxlX1JGX2ZpdCA8LSB0dW5lOjpmaXRfcmVzYW1wbGVzKFJGX3dmbG93LCB2Zm9sZF9wbSkKY29sbGVjdF9tZXRyaWNzKHJlc2FtcGxlX1JGX2ZpdCkKYGBgCgpOb3cgbGV0J3MgY29tcGFyZSB0aGUgcGVyZm9ybWFuY2Ugb2YgdGhpcyBtb2RlbCB3aXRoIG91ciBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbDoKCmBgYHtyfQojIG91ciBpbml0aWFsIGxpbmVhciByZWdyZXNzaW9uIG1vZGVsOgpjb2xsZWN0X21ldHJpY3MocmVzYW1wbGVfZml0KQpgYGAKCk9LLCBzbyBvdXIgZmlyc3QgbW9kZWwgaGFkIGEgbWVhbiBgcm1zZWAgdmFsdWUgb2YgMi4xNy4KSXQgbG9va3MgbGlrZSB0aGUgcmFuZG9tIGZvcmVzdCBtb2RlbCBoYWQgIGEgbXVjaCBsb3dlciBgcm1zZWAgdmFsdWUgb2YgMS43Mi4KCgojIyMjIHsudGhpbmtfcXVlc3Rpb25fYmxvY2t9CjxiPjx1PiBRdWVzdGlvbiBPcHBvcnR1bml0eSA8L3U+PC9iPgoKRG8geW91IHJlY2FsbCBob3cgdGhlIFJNU0UgaXMgY2FsY3VsYXRlZD8KIyMjIwoKKioqCgo8ZGV0YWlscz4gPHN1bW1hcnk+IENsaWNrIGhlcmUgdG8gcmV2ZWFsIHRoZSBhbnN3ZXIuIDwvc3VtbWFyeT4KJCRSTVNFID0gXHNxcnR7XGZyYWN7XHN1bV97aT0xfV57bn17KFxoYXR7eV90fS0geV90KX1eMn17bn19JCQKPC9kZXRhaWxzPiAKCklmIHdlIHR1bmVkIG91ciByYW5kb20gZm9yZXN0IG1vZGVsIGJhc2VkIG9uIHRoZSBudW1iZXIgb2YgdHJlZXMgb3IgdGhlIHZhbHVlIGZvciBgbXRyeWAgKHdoaWNoIGlzICJUaGUgbnVtYmVyIG9mIHByZWRpY3RvcnMgdGhhdCB3aWxsIGJlIHJhbmRvbWx5IHNhbXBsZWQgYXQgZWFjaCBzcGxpdCB3aGVuIGNyZWF0aW5nIHRoZSB0cmVlIG1vZGVscyIpLCB3ZSBtaWdodCBnZXQgYSBtb2RlbCB3aXRoIGV2ZW4gYmV0dGVyIHBlcmZvcm1hbmNlLgoKSG93ZXZlciwgb3VyIGNyb3NzIHZhbGlkYXRlZCBtZWFuIHJtc2UgdmFsdWUgb2YgMS43MiBpcyBxdWl0ZSBnb29kIGJlY2F1c2Ugb3VyIHJhbmdlIG9mIHRydWUgb3V0Y29tZSB2YWx1ZXMgaXMgbXVjaCBsYXJnZXI6IChgciByb3VuZChyYW5nZSh0ZXN0X3BtJHZhbHVlKSwzKWApLgoKCiMjIE1vZGVsIHR1bmluZwoKW0h5cGVycGFyYW1ldGVyc10oaHR0cHM6Ly9tYWNoaW5lbGVhcm5pbmdtYXN0ZXJ5LmNvbS9kaWZmZXJlbmNlLWJldHdlZW4tYS1wYXJhbWV0ZXItYW5kLWEtaHlwZXJwYXJhbWV0ZXIvKSBhcmUgb2Z0ZW4gdGhpbmdzIHRoYXQgd2UgbmVlZCB0byBzcGVjaWZ5IGFib3V0IGEgbW9kZWwuIEZvciBleGFtcGxlLCB0aGUgbnVtYmVyIG9mIHByZWRpY3RvciB2YXJpYWJsZXMgKG9yIGZlYXR1cmVzKSB0aGF0IHdpbGwgYmUgcmFuZG9tbHkgc2FtcGxlZCBhdCBlYWNoIHNwbGl0IHdoZW4gY3JlYXRpbmcgdGhlIHRyZWUgbW9kZWxzIGNhbGxlZCBgbXRyeWAgaXMgYSBoeXBlcnBhcmFtZXRlci4gVGhlIGRlZmF1bHQgbnVtYmVyIGZvciByZWdyZXNzaW9uIGFuYWx5c2VzIGlzIHRoZSBudW1iZXIgb2YgcHJlZGljdG9ycyBkaXZpZGVkIGJ5IDMuIEluc3RlYWQgb2YgYXJiaXRyYXJpbHkgc3BlY2lmeWluZyB0aGlzLCB3ZSBjYW4gdHJ5IHRvIGRldGVybWluZSB0aGUgYmVzdCBvcHRpb24gZm9yIG1vZGVsIHBlcmZvcm1hbmNlIGJ5IGEgcHJvY2VzcyBjYWxsZWQgdHVuaW5nLiAKCgpOb3cgbGV0J3MgdHJ5IHNvbWUgdHVuaW5nLgoKTGV0J3MgdGFrZSBhIGNsb3NlciBsb29rIGF0IHRoZSBgbXRyeWAgYW5kIGBtaW5fbmAgaHlwZXJwYXJhbWV0cnMgaW4gb3VyIFJhbmRvbSBGb3Jlc3QgbW9kZWwuCgpXZSBhcmVuJ3QgZXhhY3RseSBzdXJlIHdoYXQgdmFsdWVzIG9mIGBtdHJ5YCBhbmQgYG1pbl9uYCBhY2hpZXZlIGdvb2QgYWNjdXJhY3kgeWV0IGtlZXAgb3VyIG1vZGVsIGdlbmVyYWxpemFibGUgZm9yIG90aGVyIGRhdGEuCgpUaGlzIGlzIHdoZW4gb3VyIGNyb3NzIHZhbGlkYXRpb24gbWV0aG9kcyBiZWNvbWUgcmVhbGx5IGhhbmR5IGJlY2F1c2Ugbm93IHdlIGNhbiB0ZXN0IG91dCBkaWZmZXJlbnQgdmFsdWVzIGZvciBlYWNoIG9mIHRoZXNlIGh5cGVycGFyYW1ldGVycyB0byBhc3Nlc3Mgd2hhdCB2YWx1ZXMgc2VlbSB0byB3b3JrIGJlc3QgZm9yIG1vZGVsIHBlcmZvcm1hbmNlIG9uIHRoZXNlIHJlc2FtcGxlcyBvZiBvdXIgdHJhaW5pbmcgc2V0IGRhdGEuCgpQcmV2aW91c2x5IHdlIHNwZWNpZmllZCBvdXIgbW9kZWwgbGlrZSBzbzoKYGBge3J9ClJGX1BNX21vZGVsIDwtIAogIHBhcnNuaXA6OnJhbmRfZm9yZXN0KG10cnkgPSAxMCwgbWluX24gPSAzLCAKICAgICAgICAgICAgICAgICAgICAgICBtb2RlID0gInJlZ3Jlc3Npb24iKSAlPiUKICBzZXRfZW5naW5lKCJyYW5kb21Gb3Jlc3QiKSAlPiUKICBzZXRfbW9kZSgicmVncmVzc2lvbiIpCgpSRl9QTV9tb2RlbApgYGAKTm93IGluc3RlYWQgb2Ygc3BlY2lmeWluZyBhIHZhbHVlIGZvciB0aGUgYG10cnlgIGFuZCBgbWluX25gIGFyZ3VtZW50cywgd2UgY2FuIHVzZSB0aGUgYHR1bmUoKWAgZnVuY3Rpb24gb2YgdGhlIGB0dW5lYCBwYWNrYWdlIGxpa2Ugc286IGBtdHJ5ID0gdHVuZSgpYC4gVGhpcyBpbmRpY2F0ZXMgdGhhdCB0aGVzZSBoeXBlcnBhcmFtZXRlcnMgYXJlIHRvIGJlIHR1bmVkLiAKCmBgYHtyfQoKdHVuZV9SRl9tb2RlbCA8LSByYW5kX2ZvcmVzdChtdHJ5ID0gdHVuZSgpLCBtaW5fbiA9IHR1bmUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RlID0gInJlZ3Jlc3Npb24iKSAlPiUKICBzZXRfZW5naW5lKCJyYW5kb21Gb3Jlc3QiKSAlPiUKICBzZXRfbW9kZSgicmVncmVzc2lvbiIpCiAgICAKCnR1bmVfUkZfbW9kZWwKCmBgYAoKCkFnYWluIHdlIHdpbGwgYWRkIHRoaXMgdG8gYSB3b3JrZmxvdywgdGhlIG9ubHkgZGlmZmVyZW5jZSBoZXJlIGlzIHRoYXQgd2UgYXJlIHVzaW5nIGEgZGlmZmVyZW50IG1vZGVsIHNwZWNpZmljYXRpb24gd2l0aCBgdHVuZV9SRl9tb2RlbGAgaW5zdGVhZCBvZiBgUkZfbW9kZWxgOgoKYGBge3J9CgpSRl90dW5lX3dmbG93IDwtIHdvcmtmbG93czo6d29ya2Zsb3coKSAlPiUKICAgICAgICAgICAgd29ya2Zsb3dzOjphZGRfcmVjaXBlKFJGX3JlYykgJT4lCiAgICAgICAgICAgIHdvcmtmbG93czo6YWRkX21vZGVsKHR1bmVfUkZfbW9kZWwpClJGX3R1bmVfd2Zsb3cKCmBgYAoKCk5vdyB3ZSBjYW4gdXNlIHRoZSBgdHVuZV9ncmlkKClgIGZ1bmN0aW9uIG9mIHRoZSBgdHVuZWAgcGFja2FnZSB0byBldmFsdWF0ZSBkaWZmZXJlbnQgY29tYmluYXRpb25zIG9mIHZhbHVlcyBmb3IgYG10cnlgIGFuZCBgbWluX25gIHVzaW5nIG91ciBjcm9zcyB2YWxpZGF0aW9uIHNhbXBsZXMgb2Ygb3VyIHRyYWluaW5nIHNldCAoYHZmb2xkX3BtYCkgdG8gc2VlIHdoYXQgY29tYmluYXRpb24gb2YgdmFsdWVzIHBlcmZvcm1zIGJlc3QuCgpUbyB1c2UgdGhpcyBmdW5jdGlvbiB3ZSB3aWxsIHNwZWNpZnkgdGhlIHdvcmtmbG93IHVzaW5nIHRoZSBgb2JqZWN0YCBhcmd1bWVudCAgYW5kIHRoZSBzYW1wbGVzIHRvIHVzZSB1c2luZyB0aGUgYHJlc2FtcGxlc2AgYXJndW1lbnQuIFRoZSBgZ3JpZGAgYXJndW1lbnQgc3BlY2lmaWVzIGhvdyBtYW55IHBvc3NpYmxlIG9wdGlvbnMgZm9yIGVhY2ggYXJndW1lbnQgc2hvdWxkIGJlIGF0dGVtcHRlZC4KCkJ5IGRlZmF1bHQgMTAgZGlmZmVyZW50IHZhbHVlcyB3aWxsIGJlIGF0dGVtcHRlZCBmb3IgZWFjaCBoeXBlcnBhcmFtZXRlciB0aGF0IGlzIGJlaW5nIHR1bmVkLgoKV2UgY2FuIHVzZSB0aGUgYGRvUGFyYWxsZWxgIHBhY2thZ2UgdG8gYWxsb3cgdXMgdG8gZml0IGFsbCB0aGVzZSBtb2RlbHMgdG8gb3VyIGNyb3NzIHZhbGlkYXRpb24gc2FtcGxlcyBmYXN0ZXIuIFNvIGlmIHlvdSB3ZXJlIHBlcmZvcm1pbmcgdGhpcyBvbiBhIGNvbXB1dGVyIHdpdGggbXVsdGlwbGUgY29yZXMgb3IgcHJvY2Vzc29ycywgdGhlbiBkaWZmZXJlbnQgbW9kZWxzIHdpdGggZGlmZmVyZW50IGh5cGVycGFyYW1ldGVyIHZhbHVlcyBjYW4gYmUgZml0IHRvIHRoZSBjcm9zcyB2YWxpZGF0aW9uIHNhbXBsZXMgc2ltdWx0YW5lb3VzbHkgYWNyb3NzIGRpZmZlcmVudCBjb3JlcyBvciBwcm9jZXNzb3JzLiAKCldlIG5lZWQgdG8gdXNlIGBzZXQuc2VlZCgpYCBoZXJlIGJlY2F1c2UgdGhlIHZhbHVlcyBjaG9zZW4gZm9yIGBtdHJ5YCBhbmQgYG1pbl9uYCBtYXkgdmFyeSBpZiB3ZSBwcmVmb3JtIHRoaXMgZXZhbHVhdGlvbiBhZ2FpbiBiZWNhdXNlIHRoZXkgYXJlIGNob3NlbiBzZW1pLXJhbmRvbWx5IChtZWFuaW5nIHRoYXQgdGhleSBhcmUgd2l0aGluIGEgcmFuZ2Ugb2YgcmVhc29uYWJsZSB2YWx1ZXMgYnV0IHN0aWxsIHJhbmRvbSkuCgpOb3RlOiB0aGlzIHN0ZXAgd2lsbCB0YWtlIHNvbWUgdGltZS4KCmBgYHtyfQpkb1BhcmFsbGVsOjpyZWdpc3RlckRvUGFyYWxsZWwoKQpzZXQuc2VlZCgxMjMpCnR1bmVfUkZfcmVzdWx0cyA8LSB0dW5lX2dyaWQob2JqZWN0ID0gUkZfdHVuZV93ZmxvdywgcmVzYW1wbGVzID0gdmZvbGRfcG0sIGdyaWQgPSAyMCkKdHVuZV9SRl9yZXN1bHRzCmBgYAoKClNlZSBbdGhlIHR1bmUgZ2V0dGluZyBzdGFydGVkIGd1aWRlIF0oaHR0cHM6Ly90aWR5bW9kZWxzLmdpdGh1Yi5pby90dW5lL2FydGljbGVzL2dldHRpbmdfc3RhcnRlZC5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9IGZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IGltcGxlbWVudGluZyB0aGlzIGluIGB0aWR5bW9kZWxzYC4KCklmIHlvdSB3YW50ZWQgbW9yZSBjb250cm9sIG92ZXIgdGhpcyBwcm9jZXNzIHlvdSBjb3VsZCBzcGVjaWZ5IGhvdyB0aGUgZGlmZmVyZW50IHBvc3NpYmxlIG9wdGlvbnMgZm9yIGBtdHJ5YCBhbmQgYG1pbl9uYCBpbiB0aGUgYHR1bmVfZ3JpZCgpYCBmdW5jdGlvbiB1c2luZyB0aGUgZ3JpZF8qKClgIGZ1bmN0aW9ucyBvZiB0aGUgYGRpYWxzYCBwYWNrYWdlIHRvIGNyZWF0ZSBhIG1vcmUgc3BlY2lmaWMgZ3JpZC4KCkJlIGRlZmF1bHQgdGhlIHZhbHVlcyBmb3IgdGhlIGh5cGVycGFyYW1ldGVycyBiZWluZyB0dW5lZCBhcmUgY2hvc2VuIHNlbWktcmFuZG9tbHkgKG1lYW5pbmcgdGhhdCB0aGV5IGFyZSB3aXRoaW4gYSByYW5nZSBvZiByZWFzb25hYmxlIHZhbHVlcyBidXQgc3RpbGwgcmFuZG9tKS4uCgoKTm93IHdlIGNhbiB1c2UgdGhlIGBjb2xsZWN0X21ldHJpY3MoKWAgZnVuY3Rpb24gYWdhaW4gdG8gdGFrZSBhIGxvb2sgYXQgd2hhdCBoYXBwZW5lZCB3aXRoIG91ciBjcm9zcyB2YWxpZGF0aW9uIHRlc3RzLiBXZSBjYW4gc2VlIHRoZSBkaWZmZXJlbnQgdmFsdWVzIGNob3NlbiBmb3IgYG10cnlgIGFuZCBgbWluX25gIGFuZCB0aGUgbWVhbiBybXNlIGFuZCByc3EgdmFsdWVzIGFjcm9zcyB0aGUgY3Jvc3MgdmFsaWRhdGlvbiBzYW1wbGVzLgoKYGBge3J9CnR1bmVfUkZfcmVzdWx0cyU+JQogIGNvbGxlY3RfbWV0cmljcygpCmBgYAoKV2UgY2FuIG5vdyB1c2UgdGhlIGBzaG93X2Jlc3QoKWAgZnVuY3Rpb24gYXMgaXQgd2FzIHRydWx5IGludGVuZGVkLCB0byBzZWUgd2hhdCB2YWx1ZXMgZm9yIGBtaW5fbmAgYW5kIGBtdHJ5YCByZXN1bHRlZCBpbiB0aGUgYmVzdCBwZXJmb3JtYW5jZS4KCmBgYHtyfQpzaG93X2Jlc3QodHVuZV9SRl9yZXN1bHRzLCBtZXRyaWMgPSAicm1zZSIsIG4gPTEpCmBgYApUaGVyZSB3ZSBoYXZlIGl0Li4uIGxvb2tzIGxpa2UgYW4gYG10cnlgIG9mIDE3IGFuZCBgbWluX25gIG9mIDQgaGFkIHRoZSBiZXN0IGBybXNlYCB2YWx1ZS4gWW91IGNhbiB2ZXJpZnkgdGhpcyBpbiB0aGUgYWJvdmUgb3V0cHV0LCBidXQgaXQgaXMgZWFzaWVyIHRvIGp1c3QgcHVsbCB0aGlzIHJvdyBvdXQgdXNpbmcgdGhpcyBmdW5jdGlvbi4gV2UgY2FuIHNlZSB0aGF0IHRoZSBtZWFuIGBybXNlYCB2YWx1ZSBhY3Jvc3MgdGhlIGNyb3NzIHZhbGlkYXRpb24gc2V0cyB3YXMgMS43MjAuIEJlZm9yZSB0dW5pbmcgaXQgd2FzIDEuNzI1ICB3aXRoIGEgc2ltaWxhciBgc3RkX2VycmAgc28gdGhlIHBlcmZvcm1hbmNlIHdhcyB2ZXJ5IHNsaWdodGx5IGltcHJvdmVkLgoKCiMjIEZpbmFsIG1vZGVsIHBlcmZvcm1hbmNlIGV2YWx1YXRpb24KCk5vdyB0aGF0IHdlIGhhdmUgZGVjaWRlZCB0aGF0IHdlIGhhdmUgcmVhc29uYWJsZSBwZXJmb3JtYW5jZSB3aXRoIG91ciB0cmFpbmluZyBkYXRhLCB3ZSBjYW4gc3RvcCBidWlsZGluZyBvdXIgbW9kZWwgYW5kIGV2YWx1YXRlIHBlcmZvcm1hbmNlIHdpdGggb3VyIHRlc3RpbmcgZGF0YS4gCgpIZXJlLCB3ZSB3aWxsIHVzZSB0aGUgcmFuZG9tIGZvcmVzdCBtb2RlbCB0aGF0IHdlIGJ1aWx0IHRvIHByZWRpY3QgdmFsdWVzIGZvciB0aGUgbW9uaXRvcnMgaW4gdGhlIHRlc3RpbmcgZGF0YSBhbmQgd2Ugd2lsbCB1c2UgdGhlIHZhbHVlcyBmb3IgYG10cnlgIGFuZCBgbWluX25gIHRoYXQgd2UganVzdCBkZXRlcm1pbmVkIGJhc2VkIG9uIG91ciB0dW5pbmcgYW5hbHlzaXMgdG8gYWNoaWV2ZSB0aGUgYmVzdCBwZXJmb3JtYW5jZS4KClNvLCBmaXJzdCB3ZSBuZWVkIHRvIHNwZWNpZnkgdGhlc2UgdmFsdWVzIGluIGEgd29ya2Zsb3cuIFdlIGNhbiB1c2UgdGhlIGBzZWxlY3RfYmVzdCgpYCBmdW5jdGlvbiBvZiB0aGUgYHR1bmVgIHBhY2thZ2UgdG8gZ3JhYiB0aGUgdmFsdWVzIHRoYXQgd2VyZSBkZXRlcm1pbmVkIHRvIGJlIGJlc3QgZm9yIGBtdHJ5YCBhbmQgYG1pbl9uYC4KCgoKYGBge3J9Cgp0dW5lZF9SRl92YWx1ZXM8LSBzZWxlY3RfYmVzdCh0dW5lX1JGX3Jlc3VsdHMsICJybXNlIikKdHVuZWRfUkZfdmFsdWVzCmBgYAoKTm93IHdlIGNhbiBmaW5hbGl6ZSB0aGUgbW9kZWwvd29ya2Zsb3cgdGhhdCB3ZSB3ZSB1c2VkIGZvciB0dW5pbmcgd2l0aCB0aGVzZSB2YWx1ZXMuCgoKYGBge3J9ClJGX3R1bmVkX3dmbG93IDwtUkZfdHVuZV93ZmxvdyAlPiUKICB0dW5lOjpmaW5hbGl6ZV93b3JrZmxvdyh0dW5lZF9SRl92YWx1ZXMpCmBgYAoKCldpdGggdGhlIGB3b3JrZmxvd3NgIHBhY2thZ2UsIHdlIGNhbiB1c2UgdGhlIHNwbGl0dGluZyBpbmZvcm1hdGlvbiBmb3Igb3VyIG9yaWdpbmFsIGRhdGEgYHBtX3NwbGl0YCB0byBmaXQgdGhlIGZpbmFsIG1vZGVsIG9uIHRoZSBmdWxsIHRyYWluaW5nIHNldCBhbmQgYWxzbyBvbiB0aGUgdGVzdGluZyBkYXRhIHVzaW5nIHRoZSBgbGFzdF9maXQoKWAgZnVuY3Rpb24gb2YgdGhlIGB0dW5lYCBwYWNrYWdlLiBObyBwcmUtcHJvY2Vzc2luZyBzdGVwcyBhcmUgcmVxdWlyZWQuCgpUaGUgcmVzdWx0cyB3aWxsIHNob3cgdGhlIHBlcmZvcm1hbmNlIHVzaW5nIHRoZSB0ZXN0aW5nIGRhdGEuCgoKYGBge3J9Cm92ZXJhbGxmaXQgPC10dW5lOjpsYXN0X2ZpdChSRl90dW5lZF93ZmxvdywgcG1fc3BsaXQpCiAjIG9yCm92ZXJhbGxmaXQgPC1SRl93ZmxvdyAlPiUKICB0dW5lOjpsYXN0X2ZpdChwbV9zcGxpdCkKYGBgCgpUaGUgYG92ZXJhbGxmaXRgIG91dHB1dCBoYXMgYSBsb3Qgb2YgcmVhbGx5IHVzZWZ1bCBpbmZvcm1hdGlvbiBhYm91dCBob3cgdGhlIG1vZGVsLCB0aGUgZGF0YSB0ZXN0IGFuZCB0cmFpbmluZyBzcGxpdCwgYW5kIHRoZSBwcmVkaWN0aW9ucyBmb3IgdGhlIHRlc3RpbmcgZGF0YS4KClRvIHNlZSB0aGUgcGVyZm9ybWFuY2Ugb24gdGhlIHRlc3QgZGF0YSB3ZSBjYW4gdXNlIHRoZSBgY29sbGVjdF9tZXRyaWNzKClgIGZ1bmN0aW9uIGxpa2Ugd2UgZGlkIGJlZm9yZS4KYGBge3J9CiAgY29sbGVjdF9tZXRyaWNzKG92ZXJhbGxmaXQpCiAKYGBgCgpBd2Vzb21lISBXZSBjYW4gc2VlIHRoYXQgb3VyIHJtc2Ugb2YgMS40NCBpcyBxdWl0ZSBzaW1pbGFyIHdpdGggb3VyIHRlc3RpbmcgZGF0YSBjcm9zcyB2YWxpZGF0aW9uIHNldHMuIFdlIGFjaGlldmVkIHF1aXRlIGdvb2QgcGVyZm9ybWFuY2UsIHdoaWNoIHN1Z2dlc3RzIHRoYXQgd2Ugd291bGQgY291bGQgcHJlZGljdCBvdGhlciBsb2NhdGlvbnMgd2l0aCBtb3JlIHNwYXJzZSBtb25pdG9yaW5nIGJhc2VkIG9uIG91ciBwcmVkaWN0b3JzIHdpdGggcmVhc29uYWJsZSBhY2N1cmFjeS4KCk5vdyBpZiB5b3Ugd2FudGVkIHRvIHRha2UgYSBsb29rIGF0IHRoZSBwcmVkaWN0ZWQgdmFsdWVzIGZvciB0aGUgdGVzdCBzZXQgKHRoZSAyOTIgcm93cyB3aXRoIHByZWRpY3Rpb25zIG91dCBvZiB0aGUgODc2IG9yaWdpbmFsIG1vbml0b3IgdmFsdWVzKSB5b3UgY2FuIHVzZSB0aGUgIGBjb2xsZWN0X3ByZWRpY3Rpb25zKClgIGZ1bmN0aW9uIG9mIHRoZSBgdHVuZSgpYCBwYWNrYWdlOgoKYGBge3J9CnRlc3RfcHJlZGljdGlvbnMgPC1jb2xsZWN0X3ByZWRpY3Rpb25zKG92ZXJhbGxmaXQpCmBgYAoKYGBge3IsIGV2YWwgPSBGQUxTRX0KdGVzdF9wcmVkaWN0aW9ucwpgYGAKCiMjIyMgey5zY3JvbGxhYmxlIH0KYGBge3IsIGVjaG8gPUZBTFNFfQp0ZXN0X3ByZWRpY3Rpb25zICU+JQogIHByaW50KG4gPSAxZTMpCmBgYAoKIyMjIwoKTmljZSEKCiMgKipEYXRhIFZpc3VhbGl6YXRpb24qKgoqKioKCk91ciBtYWluIHF1ZXN0aW9uIGZvciB0aGlzIGNhc2Ugc3R1ZHkgd2FzOiAgCgo+IENhbiB3ZSBwcmVkaWN0IGFubnVhbCBhdmVyYWdlIGFpciBwb2xsdXRpb24gY29uY2VudHJhdGlvbnMgYXQgdGhlIGdyYW51bGFyaXR5IG9mIHppcCBjb2RlIHJlZ2lvbmFsIGxldmVscyB1c2luZyBwcmVkaWN0b3JzIHN1Y2ggYXMgZGF0YSBhYm91dCBwb3B1bGF0aW9uIGRlbnNpdHksIHVyYmFuaXphdGlvbiwgcm9hZCBkZW5zaXR5LCBhcyB3ZWxsIGFzLCBzYXRlbGxpdGUgcG9sbHV0aW9uIGRhdGEgYW5kIGNoZW1pY2FsIG1vZGVsaW5nIGRhdGE/CgpUaHVzIGZhciwgd2UgaGF2ZSBidWlsZCBhIG1hY2hpbmUgbGVhcm5pbmcgKE1MKSBtb2RlbCB0byBwcmVkaWN0IGZpbmUgcGFydGljdWxhdGUgbWF0dGVyIGFpciBwb2xsdXRpb24gbGV2ZWxzIGJhc2VkIG9uIG91ciBwcmVkaWN0b3IgdmFyaWFibGVzIChvciBmZWF0dXJlcykuCgpOb3csIGxldCdzIG1ha2UgYSBwbG90IG9mIG91ciBwcmVkaWN0ZWQgb3V0Y29tZSB2YWx1ZXMgKCRcaGF0e1l9JCkgYW5kIGFjdHVhbCBvdXRjb21lIHZhbHVlcyAkWSQgd2Ugb2JzZXJ2ZWQuIAoKRmlyc3QsIGxldCdzIHN0YXJ0IGJ5IG1ha2luZyBhIHBsb3Qgb2Ygb3VyIG1vbml0b3JzLiAKVG8gZG8gdGhpcywgd2Ugd2lsbCB1c2UgdGhlIGZvbGxvd2luZyBwYWNrYWdlcyB0byBjcmVhdGUgYSBtYXAgb2YgdGhlIFVTOgoKMS4gYHNmYCAtIHRoZSBzaW1wbGUgZmVhdHVyZXMgcGFja2FnZSBoZWxwcyB0byBjb252ZXJ0IGdlb2dyYXBoaWNhbCBjb29yZGluYXRlcyBpbnRvIGBnZW9tZXRyeWAgdmFyaWFibGVzIHdoaWNoIGFyZSB1c2VmdWwgZm9yIG1ha2luZyAyRCBwbG90cwoyLiBgbWFwc2AgLSB0aGlzIHBhY2thZ2UgY29udGFpbnMgZ2VvZ3JhcGhpY2FsIG91dGxpbmVzIGFuZCBwbG90dGluZyBmdW5jdGlvbnMgdG8gY3JlYXRlIHBsb3RzIHdpdGggbWFwcyAKMy4gYHJuYXR1cmFsZWFydGhgLSB0aGlzIGFsbG93cyBmb3IgZWFzeSBpbnRlcmFjdGlvbiB3aXRoIG1hcCBkYXRhIGZyb20gW05hdHVyYWwgRWFydGhdKGh0dHA6Ly93d3cubmF0dXJhbGVhcnRoZGF0YS5jb20vKSB3aGljaCBpcyBhIHB1YmxpYyBkb21haW4gbWFwIGRhdGFzZXQKNC4gYHJnZW9zYCAtIHRoaXMgcGFja2FnZSBpbnRlcmZhY2VzIHdpdGggdGhlIEdlb21ldHJ5IEVuZ2luZS1PcGVuIFNvdXJjZSAoYEdFT1NgKSB3aGljaCBpcyBhbHNvIGhlbHBmdWwgZm9yIGNvb3JkaW5hdGUgY29udmVyc2lvbgoKV2Ugd2lsbCBzdGFydCB3aXRoIGdldHRpbmcgYW4gb3V0bGluZSBvZiB0aGUgVVMgd2l0aCB0aGUgYG5lX2NvdW50cmllcygpYCBmdW5jdGlvbiBvZiB0aGUgYHJuYXR1cmFsZWFydGhgIHBhY2thZ2Ugd2hpY2ggd2lsbCByZXR1cm4gcG9seWdvbnMgb2YgdGhlIGNvdW50cmllcyBpbiB0aGUgW05hdHVyYWwgRWFydGhdKGh0dHA6Ly93d3cubmF0dXJhbGVhcnRoZGF0YS5jb20vKSBkYXRhc2V0LgoKQVZPQ0FETzogU28gSSBkZWZpbml0ZWx5IGhhdmUgdGhlIGBybmF0dXJhbGVhcnRoZGF0YWAgcGFja2FnZSBpbnN0YWxsZWQsIGJ1dCBmb3Igc29tZW9uZSByZWFzb24gZXZlcnkgdGltZSBJIGdvIHRvIHJ1biB0aGUgY29kZSBiZWxvdyBpdCBzYXlzIHRoYXQgSSBuZWVkIHRvIGluc3RhbGwgdGhlIHBhY2thZ2UuIEp1c3QgY3VyaW91cyAtLSB3aGF0IHZlcnNpb24gb2YgUiBhcmUgeW91IHVzaW5nP2F2b2NhZG8gcmVzcG9uc2UgLSB0aGUgZW5kIG9mIHRoZSBjYXNlIHN0dWR5IHNob3dzIHRoaXMuLiBob3BlZnVsbHkgdGhpcyB3b3JrcyBub3cgOi8gcGxlYXNlIGxldCBtZSBrbm93IGFuZCBJIHdpbGwgZmlndXJlIGl0IG91dAoKYGBge3J9Cgp3b3JsZCA8LSBuZV9jb3VudHJpZXMoc2NhbGUgPSAibWVkaXVtIiwgcmV0dXJuY2xhc3MgPSAic2YiKQpnbGltcHNlKHdvcmxkKQoKYGBgCgoKSGVyZSB5b3UgY2FuIHNlZSB0aGUgZGF0YSBhYm91dCB0aGUgY291bnRyaWVzIGluIHRoZSB3b3JsZC4gTm90aWNlIHRoZSBgZ2VvbWV0cnlgIHZhcmlhYmxlLiBUaGlzIGlzIHVzZWQgdG8gY3JlYXRlIHRoZSBvdXRsaW5lcyB0aGF0IHdlIHdhbnQuIAoKTm93IHdlIGNhbiB1c2UgdGhlIGBnZW9tX3NmKClgIGZ1bmN0aW9uIG9mIHRoZSBgZ2dwbG90MmAgcGFja2FnZSB0byBjcmVhdGUgYSB2aXN1YWwgb2Ygc2ltcGxlIGZlYXR1cmUgKHRoZSBnZW9tZXRyeSBjb29yZGluYXRlcyBmb3VuZCBpbiB0aGUgYGdlb21ldHJ5YCB2YXJpYWJsZSkuCgpgYGB7cn0KZ2dwbG90KGRhdGEgPSB3b3JsZCkgKwogICAgZ2VvbV9zZigpIAoKYGBgCgpTbyBub3cgd2UgY2FuIHNlZSB0aGF0IHdlIGhhdmUgb3V0bGluZXMgb2YgYWxsIHRoZSBjb3VudHJpZXMgaW4gdGhlIHdvcmxkLgoKV2Ugd2FudCB0byBsaW1pdCB0aGlzIGp1c3QgdG8gdGhlIGNvb3JkaW5hdGVzIGZvciB0aGUgVVMuIFdlIHdpbGwgZG8gdGhpcyBiYXNlZCBvbiB0aGUgY29vcmRpbmF0ZXMgd2UgZm91bmQgb24gV2lraXBlZGlhLiBBY2NvcmRpbmcgdG8gdGhpcyBbbGlua10oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGlzdF9vZl9leHRyZW1lX3BvaW50c19vZl90aGVfVW5pdGVkX1N0YXRlcyNXZXN0ZXJubW9zdCl7dGFyZ2V0PSJfYmxhbmsifSwgdGhlc2UgYXJlIHRoZSBsYXRpdHVkZSBhbmQgbG9uZ2l0dWRlIGJvdW5kcyBvZiB0aGUgY29udGluZW50YWwgVVM6CgotIHRvcCA9IDQ5LjM0NTc4NjggIyBub3J0aCBsYXQKLSBsZWZ0ID0gLTEyNC43ODQ0MDc5ICMgd2VzdCBsb25nCi0gcmlnaHQgPSAtNjYuOTUxMzgxMiAjIGVhc3QgbG9uZwotIGJvdHRvbSA9ICAyNC43NDMzMTk1ICMgc291dGggbGF0CgpgYGB7cn0KCmdncGxvdChkYXRhID0gd29ybGQpICsKICAgIGdlb21fc2YoKSArCiAgICBjb29yZF9zZih4bGltID0gYygtMTI1LCAtNjYpLCB5bGltID0gYygyNC41LCA1MCksIAogICAgICAgICAgICAgZXhwYW5kID0gRkFMU0UpCmBgYApOb3cgd2UganVzdCBoYXZlIGEgcGxvdCB0aGF0IGlzIG1vc3RseSBsaW1pdGVkIHRvIHRoZSBvdXRsaW5lIG9mIHRoZSBVUy4KCk5vdyB3ZSB3aWxsIHVzZSB0aGUgYGdlb21fcG9pbnQoKWAgZnVuY3Rpb24gb2YgdGhlIGBnZ3Bsb3RgIHBhY2thZ2UgdG8gYWRkIHNjYXR0ZXIgcGxvdCBvbiB0b3Agb2YgdGhlIG1hcC4gV2Ugd2FudCB0byBzaG93IHdoZXJlIHRoZSBtb25pdG9ycyBhcmUgbG9jYXRlZCBiYXNlZCBvbiB0aGUgbGF0aXR1ZGUgYW5kIGxvbmdpdHVkZSB2YWx1ZXMgaW4gdGhlIGRhdGEuCgpgYGB7cn0KZ2dwbG90KGRhdGEgPSB3b3JsZCkgKwogICAgZ2VvbV9zZigpICsKICAgIGNvb3JkX3NmKHhsaW0gPSBjKC0xMjUsIC02NiksIHlsaW0gPSBjKDI0LjUsIDUwKSwgCiAgICAgICAgICAgICBleHBhbmQgPSBGQUxTRSkrCiAgICBnZW9tX3BvaW50KGRhdGEgPSBwbSwgYWVzKHggPSBsb24sIHkgPSBsYXQpLCBzaXplID0gMiwgCiAgICAgICAgICAgICAgIHNoYXBlID0gMjMsIGZpbGwgPSAiZGFya3JlZCIpCgpgYGAKTmljZSEKCk5vdyBsZXQncyBhZGQgY291bnR5IGxpbmVzLgoKQ291bnR5IGdyYXBoaWNhbCBkYXRhIGlzIGF2YWlsYWJsZSBmcm9tIHRoZSBgbWFwc2AgcGFja2FnZS4gClRoZSBgc2ZgIHBhY2thZ2Ugd2hpY2ggYWdhaW4gaXMgc2hvcnQgZm9yIHNpbXBsZSBmZWF0dXJlcyBjcmVhdGVzIGEgZGF0YSBmcmFtZSBhYm91dCB0aGlzIGdyYXBoaWNhbCBkYXRhIHNvIHRoYXQgd2UgY2FuIHdvcmsgd2l0aCBpdC4KCmBgYHtyfQpjb3VudGllcyA8LSAKICBzZjo6c3RfYXNfc2YobWFwczo6bWFwKCJjb3VudHkiLCBwbG90ID0gRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9IFRSVUUpKQoKY291bnRpZXMKYGBgCgpOb3cgd2Ugd2lsbCB1c2UgdGhpcyBkYXRhIHdpdGhpbiB0aGUgYGdlb21fc2YoKWAgZnVuY3Rpb24gdG8gYWRkIHRoaXMgdG8gb3VyIHBsb3QuICBXZSB3aWxsIGFsc28gYWRkIGEgdGl0bGUgdXNpbmcgdGhlIGBnZ3RpdGxlKClgIGZ1bmN0aW9uLCBhcyB3ZWxsIGFzIHJlbW92ZSBheGlzIHRpY2tzIGFuZCB0aXRsZXMgdXNpbmcgdGhlIGB0aGVtZSgpYCBmdW5jdGlvbiBvZiB0aGUgYGdncGxvdDJgIHBhY2thZ2UuCgpgYGB7cn0KbW9uaXRvcnMgPC0gZ2dwbG90KGRhdGEgPSB3b3JsZCkgKwogICAgZ2VvbV9zZihkYXRhID0gY291bnRpZXMsIGZpbGwgPSBOQSwgY29sb3IgPSBncmF5KC41KSkrCiAgICAgIGNvb3JkX3NmKHhsaW0gPSBjKC0xMjUsIC02NiksIHlsaW0gPSBjKDI0LjUsIDUwKSwgCiAgICAgICAgICAgICBleHBhbmQgPSBGQUxTRSkgKwogICAgZ2VvbV9wb2ludChkYXRhID0gcG0sIGFlcyh4ID0gbG9uLCB5ID0gbGF0KSwgc2l6ZSA9IDIsIAogICAgICAgICAgICAgICBzaGFwZSA9IDIzLCBmaWxsID0gImRhcmtyZWQiKSArCiAgICBnZ3RpdGxlKCJNb25pdG9yIExvY2F0aW9ucyIpICsKICAgIHRoZW1lKGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy55PWVsZW1lbnRfYmxhbmsoKSkKCm1vbml0b3JzCmBgYAoKR3JlYXQhCgpOb3csIGxldCdzIGFkZCBhIGZpbGwgYXQgdGhlIGNvdW50eS1sZXZlbCBmb3IgdGhlIHRydWUgbW9uaXRvciB2YWx1ZXMgb2YgYWlyIHBvbGx1dGlvbi4KCkZpcnN0LCB3ZSBuZWVkIHRvIGdldCB0aGUgY291bnR5IG1hcCBkYXRhIHRoYXQgd2UganVzdCBnb3QgYW5kIG91ciBhaXIgcG9sbHV0aW9uIGRhdGEgdG8gaGF2ZSBzaW1pbGFybHkgZm9ybWF0dGVkIGNvdW50eSBuYW1lcyBzbyB0aGF0IHdlIGNhbiBjb21iaW5lIHRoZSBkYXRhc2V0cyB0b2dldGhlci4KCldlIGNhbiBzZWUgdGhhdCBpbiB0aGUgYGNvdW50eWAgZGF0YSB0aGUgY291bnRpZXMgYXJlIGxpc3RlZCBhZnRlciB0aGUgc3RhdGUgbmFtZSBhbmQgYSBjb21tYS4gSW4gYWRkaXRpb24gdGhleSBhcmUgYWxsIGxvd2VyIGNhc2UuCgoKYGBge3J9CmhlYWQoY291bnRpZXMpCmBgYAoKSW4gY29udHJhc3QsIG91ciBhaXIgcG9sbHV0aW9uIGBwbWAgZGF0YSBzaG93cyBjb3VudGllcyBhcyB0aXRsZXMgd2l0aCB0aGUgZmlyc3QgbGV0dGVyIGFzIHVwcGVyIGNhc2UuIAoKYGBge3J9CmRwbHlyOjpwdWxsKHBtLCBjb3VudHkpICU+JQogIGhlYWQoKQpgYGAKCldlIGNhbiB1c2UgdGhlIGBzZXBhcmF0ZSgpYCBmdW5jdGlvbiBvZiB0aGUgYHRpZHlyYCBwYWNrYWdlIHRvIHNlcGFyYXRlIHRoZSBgSURgIHZhcmlhYmxlIG9mIG91ciBgY291bnRpZXNgIGRhdGEgaW50byB0d28gYHZhcmlhYmxlc2AgYmFzZWQgb24gdGhlIGNvbW1hIGFzIGEgc2VwYXJhdG9yLgoKYGBge3J9CmNvdW50aWVzICU8PiUgCiAgdGlkeXI6OnNlcGFyYXRlKElELCBpbnRvID0gYygic3RhdGUiLCAiY291bnR5IiksIHNlcCA9ICIsIikKCmhlYWQoY291bnRpZXMpCmBgYApOb3cgd2UganVzdCBuZWVkIHRvIG1ha2UgdGhlc2UgbmFtZXMgaW4gdGhlIG5ldyBgY291bnR5YCB2YXJpYWJsZSBvZiB0aGUgYGNvdW50aWVzYCBkYXRhIHRvIGJlIGluIHRpdGxlIGZvcm1hdC4gV2UgY2FuIHVzZSB0aGUgYHN0cl90b190aXRsZSgpYCBmdW5jdGlvbiBvZiB0aGUgYHN0cmluZ3JgIHBhY2thZ2UgdG8gZG8gdGhpcy4gCmBgYHtyfQpjb3VudGllc1tbImNvdW50eSJdXSA8LSBzdHJpbmdyOjpzdHJfdG9fdGl0bGUoY291bnRpZXNbWyJjb3VudHkiXV0pCmBgYAoKR3JlYXQhIE5vdyB0aGUgY291bnR5IGluZm9ybWF0aW9uIGlzIHRoZSBzYW1lIGZvciB0aGUgYGNvdW50aWVzYCBhbmQgYHBtYCBkYXRhLgoKV2UgY2FuIHVzZSB0aGUgYGlubmVyX2pvaW4oKWAgZnVuY3Rpb24gb2YgdGhlIGBkcGx5cmAgcGFja2FnZSB0byBqb2luIHRoZSBkYXRhc2V0cyB0b2dldGhlciBiYXNlZCBvbiB0aGUgYGNvdW50eWAgdmFyaWFibGVzIGluIGVhY2guIFRoaXMgZnVuY3Rpb24gd2lsbCBrZWVwIGFsbCByb3dzIHRoYXQgYXJlIGluIGJvdGggZGF0YXNldHMuCgpgYGB7cn0KbWFwX2RhdGEgPC1kcGx5cjo6aW5uZXJfam9pbihjb3VudGllcywgcG0sIGJ5ID0gImNvdW50eSIpCgpnbGltcHNlKG1hcF9kYXRhKQoKYGBgCk5pY2UhIHdlIGNhbiBzZWUgdGhhdCB3ZSBoYXZlIGFkZCBhIGBnZW9tYCB2YXJpYWJsZSB0byB0aGUgYHBtYCBkYXRhLgoKTm93IHdlIGNhbiB1c2UgdGhpcyB0byBjb2xvciB0aGUgY291bnRpZXMgaW4gb3VyIHBsb3QgYmFzZWQgb24gdGhlIGB2YWx1ZWAgdmFyaWFibGUgb2Ygb3VyIGBwbWAgZGF0YSwgd2hpY2ggeW91IG1heSByZWNhbGwgaXMgdGhlIGFjdHVhbCBtb25pdG9yIGRhdGEgZm9yIGZpbmUgcGFydGljdWxhdGUgYWlyIHBvbGx1dGlvbiBhdCBlYWNoIG1vbml0b3IuIAoKV0UgY2FuIGRvIHNvIHVzaW5nIHRoZSBgc2NhbGVfZmlsbF9ncmFkaWVudG4oKWAgZnVuY3Rpb24gb2YgdGhlIGBnZ3Bsb3QyYCBwYWNrYWdlIHdoaWNoIGNyZWF0ZXMgY29sb3IgZ3JhZGllbnQgYmFzZWQgb24gYSB2YXJpYWJsZS4gSW4gdGhpcyBjYXNlIGl0IGlzIHRoZSB2YXJpYWJsZSB0aGF0IHdhcyBzcGVjaWZpZWQgYXMgdGhlIGBmaWxsYCBpbiB0aGUgYGFlc2AgZnVuY3Rpb24gb2YgdGhlIGBnZW9tX3NmKClgIGZ1bmN0aW9uLiBXZSBzcGVjaWZpZWQgdGhhdCBpdCB3b3VsZCBiZSB0aGUgYHZhbHVlYCB2YXJpYWJsZSBvZiB0aGUgYHBtYCBkYXRhLgoKVGhpcyBgc2NhbGVfZmlsbF9ncmFkaWVudG4oKWAgZnVuY3Rpb24gIGFsc28gYWxsb3dzIHlvdSB0byBzcGVjaWZ5IHRoZSBjb2xvcnMsIHdoYXQgdG8gZG8gYWJvdXQgTkEgdmFsdWVzIChzaG91bGQgdGhleSBiZSBhIHNwZWNpZmljIGNvbG9yIG9yIHRyYW5zcGFyZW50KSBhbmQgdGhlIGJyZWFrcywgbGltaXRzLCBsYWJlbHMgYW5kIG5hbWUvdGl0bGUgb24gdGhlIGxlZ2VuZCBmb3IgdGhlIGNvbG9yIGdyYWRpZW50LiAKCmBgYHtyfQoKdHJ1dGggPC1nZ3Bsb3QoZGF0YSA9IHdvcmxkKSArCiAgY29vcmRfc2YoeGxpbSA9IGMoLTEyNSwgLTY2KSwgeWxpbSA9IGMoMjQuNSwgNTApLCBleHBhbmQgPSBGQUxTRSkrCiAgICBnZW9tX3NmKGRhdGEgPSBtYXBfZGF0YSwgYWVzKGZpbGwgPSB2YWx1ZSkpICsKICBzY2FsZV9maWxsX2dyYWRpZW50bihjb2xvdXJzPXRvcG8uY29sb3JzKDcpLCBuYS52YWx1ZSA9ICJ0cmFuc3BhcmVudCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcz1jKDAsMTAsMjApLGxhYmVscz1jKDAsMTAsMjApLAogICAgICAgICAgICAgICAgICAgICAgICAgICBsaW1pdHM9YygwLDIzLjUpLCBuYW1lID0gIlBNIHVnL20zIikgKwogIGdndGl0bGUoIlRydWUgUE0gMi41IGxldmVscyIpICsKICAgIHRoZW1lKGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy55PWVsZW1lbnRfYmxhbmsoKSkKCnRydXRoCgpgYGAKTmljZSEKCk5vdyBsZXQncyBkbyB0aGUgc2FtZSB3aXRoIG91ciBwcmVkaWN0ZWQgb3V0Y29tZSB2YWx1ZXMuCgpMZXQncyBncmFiIGJvdGggdGhlIHRlc3RpbmcgYW5kIHRyYWluaW5nIHByZWRpY3RlZCBvdXRjb21lIHZhbHVlcyBzbyB0aGF0IHdlIGhhdmUgYXMgbXVjaCBkYXRhIGFzIHBvc3NpYmxlLiAKCkZpcnN0IHdlIG5lZWQgdG8gZml0IG91ciB0cmFpbmluZyBkYXRhIHdpdGggb3VyIGZpbmFsIG1vZGVsIHRvIGJlIGFibGUgdG8gZ2V0IHRoZSBwcmVkaWN0aW9ucyBmb3IgdGhlIG1vbml0b3JzIGluY2x1ZGVkIGluIHRoZSB0cmFpbmluZyBzZXQuIFdlIGRpZCB0aGlzIHVzaW5nIHRoZSBgbGFzdF9maXQoKWAgZnVuY3Rpb24sIGJ1dCB0aGUgb3V0cHV0IG9mIHRoaXMgbWFrZXMgaXQgZGlmZmljdWx0IHRvIGdyYWIgdGhlIHByZWRpY3RlZCB2YWx1ZXMgZm9yIHRoZSB0cmFpbmluZyBkYXRhLCBhbmQgaXQgaXMgYWxzbyBkaWZmaWN1bHQgdG8gZ2V0IHRoZSBpZCB2YXJpYWJsZXMgZm9yIHRoZSB0ZXN0aW5nIGRhdGEuIAoKClRodXMgd2Ugd2lsbCB1c2UgdGhlIHBhcnNuaXAgYGZpdCgpYCBhbmQgIGBwcmVkaWN0KClgIGZ1bmN0aW9ucyB0byBkbyB0aGlzIG91dHNpZGUgb2YgdGhlIGB3b3JrZmxvd3NgIHBhY2thZ2UgbGlrZSBzbzoKCiMjIyMgey50aGlua19xdWVzdGlvbl9ibG9ja30KPGI+PHU+IFF1ZXN0aW9uIE9wcG9ydHVuaXR5IDwvdT48L2I+CgpXaHkgZG8gd2Ugbm90IG5lZWQgcHJlLXByb2Nlc3NlZCBkYXRhPwoKIyMjIwoKKioqCgo8ZGV0YWlscz4gPHN1bW1hcnk+IENsaWNrIGhlcmUgdG8gcmV2ZWFsIHRoZSBhbnN3ZXIuIDwvc3VtbWFyeT4KClNpbmNlIHdlIGFyZSB1c2luZyBhIHdvcmtmbG93LCB0aGUgZGF0YSB3aWxsIGJlIHByZS1wcm9jZXNzZWQgd2hlbiBpdCBpcyBmaXQgYXMgd2VsbC4KCjwvZGV0YWlscz4KKioqCgoKYGBge3J9CgpSRl9maW5hbF90cmFpbl9maXQgPC0gcGFyc25pcDo6Zml0KFJGX3R1bmVkX3dmbG93LCBkYXRhID0gdHJhaW5fcG0pClJGX2ZpbmFsX3Rlc3RfZml0IDwtIHBhcnNuaXA6OmZpdChSRl90dW5lZF93ZmxvdywgZGF0YSA9IHRlc3RfcG0pCgoKdmFsdWVzX3ByZWRfdHJhaW4gPC0gCiAgcHJlZGljdChSRl9maW5hbF90cmFpbl9maXQsIHRyYWluX3BtKSAlPiUgCiAgYmluZF9jb2xzKHRyYWluX3BtICU+JSBzZWxlY3QodmFsdWUsIGZpcHMsIGNvdW50eSwgaWQpKSAKCnZhbHVlc19wcmVkX3RyYWluCgp2YWx1ZXNfcHJlZF90ZXN0IDwtIAogIHByZWRpY3QoUkZfZmluYWxfdGVzdF9maXQsIHRlc3RfcG0pICU+JSAKICBiaW5kX2NvbHModGVzdF9wbSAlPiUgc2VsZWN0KHZhbHVlLCBmaXBzLCBjb3VudHksIGlkKSkgCgp2YWx1ZXNfcHJlZF90ZXN0CmBgYAoKTm93IHdlIGNhbiBjb21iaW5lIHRoaXMgZGF0YSBmb3IgdGhlIHByZWRpY3Rpb25zIGZvciBhbGwgbW9uaXRvcnMgdXNpbmcgdGhlIGBiaW5kX3Jvd3MoKWAgZnVuY3Rpb24gb2YgdGhlIGBkcGx5cmAgcGFja2FnZSwgd2hpY2ggd2lsbCBlc3NlbnRpYWxseSBhcHBlbmQgdGhlIHNlY29uZCBkYXRhc2V0IHRvIHRoZSBmaXJzdC4KCmBgYHtyfQphbGxfcHJlZCA8LSBiaW5kX3Jvd3ModmFsdWVzX3ByZWRfdGVzdCwgdmFsdWVzX3ByZWRfdHJhaW4pCgphbGxfcHJlZApgYGAKCkdyZWF0ISBhcyB3ZSBjYW4gc2VlIHRoZXJlIGFyZSA4NzYgdmFsdWVzIGxpa2Ugd2Ugd291bGQgZXhwZWN0IGZvciBhbGwgb2YgdGhlIG1vbml0b3JzLiBXZSBjYW4gdXNlIHRoZSBgY291bnR5YCB2YXJpYWJsZSB0byBjb21iaW5lIHRoaXMgd2l0aCB0aGUgYGNvdW50aWVzYCBkYXRhIGxpa2Ugd2UgZGlkIHdpdGggdGhlIGBwbWAgZGF0YSBwcmV2aW91c2x5IHNvIHRoYXQgd2UgY2FuIHVzZSB0aGUgYHZhbHVlYCB2YXJpYWJsZSBhcyBhIGNvbG9yIHNjaGVtZSBmb3Igb3VyIG1hcC4KCgpgYGB7cn0KbWFwX2RhdGEgPC0gaW5uZXJfam9pbihjb3VudGllcywgYWxsX3ByZWQsIGJ5ID0gImNvdW50eSIpCgpwcmVkIDwtIGdncGxvdChkYXRhID0gd29ybGQpICsKICAgICAgICAgIGNvb3JkX3NmKHhsaW0gPSBjKC0xMjUsIC02NiksIHlsaW0gPSBjKDI0LjUsIDUwKSwgCiAgICAgICAgICAgICAgICAgZXhwYW5kID0gRkFMU0UpICsKICAgIGdlb21fc2YoZGF0YSA9IG1hcF9kYXRhLCBhZXMoZmlsbCA9IC5wcmVkKSkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKGNvbG91cnM9dG9wby5jb2xvcnMoNyksIG5hLnZhbHVlID0gInRyYW5zcGFyZW50IiwKICAgICAgICAgICAgICAgICAgICAgICBicmVha3M9YygwLDEwLDIwKSxsYWJlbHM9YygwLDEwLDIwKSwKICAgICAgICAgICAgICAgICAgICAgICBsaW1pdHM9YygwLDIzLjUpLCBuYW1lID0gIlBNIHVnL20zIikgKwogIGdndGl0bGUoIlByZWRpY3RlZCBQTSAyLjUgbGV2ZWxzIikrCiAgICB0aGVtZShheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzLng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGl0bGUueT1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MueT1lbGVtZW50X2JsYW5rKCkpCgpwcmVkCmBgYAoKTm93IHdlIHdpbGwgdXNlIHRoZSBgcGF0Y2h3b3JrYCBwYWNrYWdlIHRvIGNvbWJpbmUgb3VyIGxhc3QgdHdvIHBsb3RzLiBUaGlzIGFsbG93cyB1cyB0byBjb21iaW5lIHBsb3RzIHVzaW5nIHRoZSBgK2Agb3IgdGhlIGAvYCAuIFRoZSBgK2Agd2lsbCBwbGFjZSBwbG90cyBzaWRlIGJ5IHNpZGUgYW5kIHRoZSBgL2Agd2lsbCBwbGFjZSBwbG90cyB0b3AgdG8gYm90dG9tLgoKCk5vdyBsZXQncyBqdXN0IGNvbWJpbmUgdGhlIHRydXRoIHBsb3QgYW5kIHRoZSBwcmVkaWN0aW9uIHBsb3RzIHRvZ2V0aGVyOgpgYGB7cn0KdHJ1dGgvcHJlZAoKYGBgCgpXZSBjYW4gc2VlIHRoYXQgdGhlIHByZWRpY3RlZCBmaW5lIHBhcnRpY2xlIGFpciBwb2xsdXRpb24gdmFsdWVzIGluICh1Zy9tMykgYXJlIHF1aXRlIHNpbWlsYXIgdG8gdGhlIHRydWUgdmFsdWVzIG1lYXN1cmVkIGJ5IHRoZSBhY3R1YWwgZ3JhdmltZXRyaWMgbW9uaXRvcnMuIFdlIGNhbiBhbHNvIHNlZSB0aGF0IHNvdXRoZXJuIENhbGlmb3JuaWEgaGFzIHNvbWUgbGFyZ2UgY291bnRpZXMgd2l0aCB3b3JzZSBwb2xsdXRpb24gKGFzIHRoZXkgYXJlIHllbGxvdyBhbmQgdGh1cyBoYXZlIG11Y2ggaGlnaGVyIHBhcnRpY3VsYXRlIG1hdHRlciBsZXZlbHMpLgoKTGV0J3MgYWRkIHNvbWUgdGV4dCB0byBvdXIgcGxvdCB0byBleHBsYWluIGl0IGEgYml0IG1vcmUuCgpgYGB7cn0KdHJ1dGgvcHJlZCArIHBsb3RfYW5ub3RhdGlvbih0aXRsZSA9ICJSYW5kb20gZm9yZXN0IG1vZGVsIHByZWRpY3RzIGZpbmUgcGFydGljdWxhdGUgbWF0dGVyIChQTSAyLjUpIFxuYWlyIHBvbGx1dGlvbiBiYXNlZCBvbiBkYXRhIGFib3V0IHJvYWQgcHJveGltaXR5LCBwb3B1bGF0aW9uIGRlbnNpdHksXG5hbmQgb3RoZXIgcHJlZGljdG9ycyByZWFzb25hYmx5IHdlbGwiKQoKYGBgCgoKYGBge3IsIGVjaG8gPSBGQUxTRSwgbWVzc2FnZT1GQUxTRSwgZXZhbD1GQUxTRX0KcG5nKGhlcmU6OmhlcmUoImltZyIsICJtYWluX3Bsb3RfbWFwcy5wbmciKSwgCiAgICBoZWlnaHQgPSAxNTAwLCB3aWR0aCA9IDIwMDAsIHJlcyA9IDMwMCkKdHJ1dGgvcHJlZCArIHBsb3RfYW5ub3RhdGlvbih0aXRsZSA9ICJSYW5kb20gZm9yZXN0IG1vZGVsIHByZWRpY3RzIGZpbmUgcGFydGljdWxhdGUgbWF0dGVyIChQTSAyLjUpIFxuYWlyIHBvbGx1dGlvbiBiYXNlZCBvbiBkYXRhIGFib3V0IHJvYWQgcHJveGltaXR5LCBwb3B1bGF0aW9uIGRlbnNpdHksXG5hbmQgb3RoZXIgcHJlZGljdG9ycyByZWFzb25hYmx5IHdlbGwiKQpkZXYub2ZmKCkKYGBgCgojICoqU3VtbWFyeSoqCioqKgoKIyMgU3lub3BzaXMKCkluIHRoaXMgY2FzZSBzdHVkeSwgd2UgZXhwbG9yZWQgZ3JhdmltZXRyaWMgbW9uaXRvcmluZyBkYXRhIG9mIGZpbmUgcGFydGljdWxhdGUgbWF0dGVyIGFpciBwb2xsdXRpb24gKG91dGNvbWUgdmFyaWFibGUpLiAKT3VyIGdvYWwgd2FzIHRvIGFibGUgdG8gcHJlZGljdCBhaXIgcG9sbHV0aW9uIG9uIG1vbml0b3JzIHdoZXJlIHdlIG9ubHkgaGFkIHByZWRpY3RvciB2YXJpYWJsZXMgKG9yIGZlYXR1cmVzKSB3aXRob3V0IGhhdmluZyBvYnNlcnZlZCBhIGNvcnJlc3BvbmRpbmcgbWVhc3VyZW1lbnQgb2YgYWlyIHBvbGx1dGlvbi4KCk91ciBsZWFybmluZyBvYmplY3RpdmVzIHdlcmU6IAoKLSBJbnRyb2R1Y2UgY29uY2VwdHMgaW4gbWFjaGluZSBsZWFybmluZwotIERlbW9uc3RyYXRlIGhvdyB0byBidWlsZCBhIG1hY2hpbmUgbGVhcm5pbmcgbW9kZWwgd2l0aCBgdGlkeW1vZGVsc2AKLSBEZW1vbnN0cmF0ZSBob3cgdG8gdmlzdWFsaXplIGdlby1zcGF0aWFsIGRhdGEgdXNpbmcgYGdncGxvdDJgCgpVc2luZyB0aGUgbWFjaGluZSBsZWFybmluZyBtb2RlbHMgYnVpbHQgaW4gdGhpcyBjYXNlIHN0dWR5LCB3ZSBjb3VsZCBub3cgZXh0ZW5kIHRoaXMgbW9kZWwgdG8gYmUgdXNlZCB0byBwcmVkaWN0IGFpciBwb2xsdXRpb24gbGV2ZWxzIGluIGFyZWFzIHdpdGggcG9vciBtb25pdG9yaW5nLCB0byBoZWxwIGlkZW50aWZ5IHJlZ2lvbnMgd2hlcmUgcG9wdWxhdGlvbnMgbWF5YmUgZXNwZWNpYWxseSBhdCByaXNrIGZvciB0aGUgaGVhbHRoIGVmZmVjdHMgb2YgYWlyIHBvbGx1dGlvbi4gIAoKQW5hbHlzZXMgbGlrZSB0aGUgb25lIGluIG91ciBjYXNlIHN0dWR5IGFyZSBpbXBvcnRhbnQgZm9yIGRlZmluaW5nIHdoaWNoIGdyb3VwcyBjb3VsZCBiZW5lZml0IHRoZSBtb3N0IGZyb20gaW50ZXJ2ZW50aW9ucywgZWR1Y2F0aW9uLCBhbmQgcG9saWN5IGNoYW5nZXMgd2hlbiBhdHRlbXB0aW5nIHRvIG1pdGlnYXRlIHB1YmxpYyBoZWFsdGggY2hhbGxlbmdlcy4gWW91IGNhbiBzZWUgaW4gdGhpcyBbYXJ0aWNsZV0oaHR0cHM6Ly93d3cubmVqbS5vcmcvZG9pL2Z1bGwvMTAuMTA1Ni9ORUpNb2ExNzAyNzQ3KXt0YXJnZXQ9Il9ibGFuayJ9IHRoYXQgbWFueSBhZGRpdGlvbmFsIGNvbnNpZGVyYXRpb25zIHdvdWxkIGJlIGludm9sdmVkIHRvIGFkZXF1YXRlbHkgdW5kZXJzdGFuZCB0aGUgZGF0YSBlbm91Z2ggdG8gcmVjb21tZW5kIHBvbGljeSBjaGFuZ2VzLgoKCjxkZXRhaWxzPjxzdW1tYXJ5PiBDbGljayBoZXJlIGZvciBtb3JlIG9uIHdoYXQgd2UgbGVhcm5lZCB3aXRoIGB0aWR5bW9kZWxzYCA8L3N1bW1hcnk+CgpIZXJlLCB3ZSBwcm92aWRlIGFuIG92ZXJ2aWV3IG9mIHRoZSBgdGlkeW1vZGVsc2AgZnJhbWV3b3JrLiAKYXZvY2Fkby4uLiB0d28gb3B0aW9uczoKCmBgYHtyLCBlY2hvPUZBTFNFLCBvdXQud2lkdGg9IjgwMHB4In0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1nIiwiZWNvc3lzdGVtLnBuZyIpKQpgYGAKCgpgYGB7ciwgZWNobz1GQUxTRSwgb3V0LndpZHRoPSI4MDBweCJ9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltZyIsIm5ld190aWR5bW9kZWxzX2Vjb3N5c3RlbS5wbmciKSkKYGBgCgpXZSBwZXJmb3JtZWQgdGhlIG1ham9yIHN0ZXBzIG9mIG1hY2hpbmUgbGVhcm5pbmcgdGhhdCB3ZSBpbnRyb2R1Y2VkIGluIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGRhdGEgYW5hbHlzaXM6ICAKCjEuIERhdGEgZXhwbG9yYXRpb24gIAoKV2UgdXNlZCBwYWNrYWdlcyBsaWtlIGBza2ltcmAsIGBzdW1tYXJ5dG9vbHNgLCBgY29ycnBsb3RgLCBhbmQgYEdHYWxseWAgdG8gYmV0dGVyIHVuZGVyc3RhbmQgb3VyIGRhdGEuIFRoZXNlIHBhY2thZ2VzIGdhdmUgY2FuIHRlbGwgdXMgaG93IG1hbnkgbWlzc2luZyB2YWx1ZXMgZWFjaCB2YXJpYWJsZSBoYXMgKGlmIGFueSksIHRoZSBjbGFzcyBvZiBlYWNoIHZhcmlhYmxlLCB0aGUgZGlzdHJpYnV0aW9uIG9mIHZhbHVlcyBmb3IgZWFjaCB2YXJpYWJsZSwgdGhlIHNwYXJzaXR5IG9mIGVhY2ggdmFyaWFibGUsIGFuZCB0aGUgbGV2ZWwgb2YgY29ycmVsYXRpb24gYmV0d2VlbiB2YXJpYWJsZXMuICAKCjIuIERhdGEgc3BsaXR0aW5nIAoKV2UgdXNlZCB0aGUgYHJzYW1wbGVgIHBhY2thZ2UgdG8gZmlyc3QgcGVyZm9ybSBhbiBpbml0aWFsIHNwbGl0IG9mIG91ciBkYXRhIGludG8gdHdvIHBpZWNlczogYSB0cmFpbmluZyBzZXQgYW5kIGEgdGVzdGluZyBzZXQuIFRoZSB0cmFpbmluZyBzZXQgd2FzIHVzZWQgdG8gb3B0aW1pemUgdGhlIG1vZGVsLCB3aGlsZSB0aGUgdGVzdGluZyBzZXQgd2FzIHVzZWQgb25seSB0byBldmFsdWF0ZSB0aGUgcGVyZm9ybWFuY2Ugb2Ygb3VyIGZpbmFsIG1vZGVsLiBXZSBhbHNvIHVzZWQgdGhlIGByc2FtcGxlYCBwYWNrYWdlIHRvIGNyZWF0ZSBjcm9zcyB2YWxpZGF0aW9uIHN1YnNldHMgb2Ygb3VyIHRyYWluaW5nIGRhdGEuIFRoaXMgYWxsb3dlZCB1cyB0byBiZXR0ZXIgYXNzZXNzIHRoZSBwZXJmb3JtYW5jZSBvZiBvdXIgdGVzdGVkIG1vZGVscyB1c2luZyBvdXIgdHJhaW5pbmcgZGF0YS4gIAoKMy4gVmFyaWFibGUgYXNzaWdubWVudCBhbmQgcHJlLXByb2Nlc3NpbmcgICAKCldlIHVzZWQgdGhlIGByZWNpcGVzYCBwYWNrYWdlIHRvIGFzc2lnbiB2YXJpYWJsZSByb2xlcyAoc3VjaCBhcyBvdXRjb21lLCBwcmVkaWN0b3IsIGFuZCBpZCB2YXJpYWJsZSkuIFdlIGFsc28gdXNlZCB0aGlzIHBhY2thZ2UgdG8gY3JlYXRlIGEgcmVjaXBlIGZvciBwcmUtcHJvY2Vzc2luZyBvdXIgdHJhaW5pbmcgYW5kIHRlc3RpbmcgZGF0YS4gVGhpcyBpbnZvbHZlZCBzdGVwcyBzdWNoIGFzOiBgIHN0ZXBfZHVtbXlgIHRvIGNyZWF0ZSBkdW1teSBudW1lcmljIGVuY29kaW5ncyBvZiBvdXIgY2F0ZWdvcmljYWwgdmFyaWFibGVzLCBgc3RlcF9jb3JyYCB0byByZW1vdmUgaGlnaGx5IGNvcnJlbGF0ZWQgdmFyaWFibGVzLCBgc3RlcF9uenZgIHRvIHJlbW92ZSBuZWFyIHplcm8gdmFyaWFuY2UgdmFyaWFibGVzIHRoYXQgd291bGQgY29udHJpYnV0ZSBsaXR0bGUgdG8gb3VyIG1vZGVsIGFuZCBwb3RlbnRpYWxseSBhZGQgbm9pc2UuICBXZSBsZWFybmVkIHRoYXQgb25jZSBvdXIgcmVjaXBlIHdhcyBjcmVhdGVkIGFuZCBwcmVwcGVkIHVzaW5nIGBwcmVwKClgd2UgY291bGQgZXh0cmFjdCB0aGUgcHJlLXByb2Nlc3NlZCB0cmFpbmluZyBkYXRhIHVzaW5nIGBqdWljZSgpYCBvciBvdXIgcHJlLXByb2Nlc3NlZCB0ZXN0aW5nIGRhdGEgdXNpbmcgYGJha2UoKWAuIFdlIGFsc28gbGVhcm5lZCB0aGF0IGlmIHdlIHVzZWQgdGhlIG5ld2VyIHdvcmtmbG93cyBwYWNrYWdlIHRoYXQgd2UgZGlkIG5vdCBuZWVkIHRvIHRoZSBgcHJlcCgpYCwgYGp1aWNlKClgLCBvciBgYmFrZSgpYCBmdW5jdGlvbnMsIGJ1dCB0aGF0IGl0IGlzIHN0aWxsIHVzZWZ1bCB0byBrbm93IGhvdyB0byBkbyBzbyBpZiB3ZSB3YW50IHRvIGxvb2sgYXQgb3VyIGRhdGEgYW5kIGhvdyB0aGUgcmVjaXBlIGlzIGluZmx1ZW5jaW5nIGl0IG1vcmUgZGVlcGx5LiAgCgo0LiBNb2RlbCBzcGVjaWZpY2F0aW9uLCBmaXR0aW5nLCB0dW5pbmcgYW5kIHBlcmZvcm1hbmNlIGV2YWx1YXRpb24gdXNpbmcgdGhlIHRyYWluaW5nIGRhdGEgIAoKV2UgbGVhcm5lZCB0aGF0IHRoZSBtb2RlbCBuZWVkcyB0byBmaXJzdCBiZSBmaXQgdG8gdGhlIHRyYWluaW5nIGRhdGEuIFdlIGxlYXJuZWQgdGhhdCBpbiBib3RoIGNsYXNzaWZpY2F0aW9uIGFuZCBwcmVkaWN0aW9uLCB0aGUgbW9kZWwgaXMgZml0IHRvIHRoZSB0cmFpbmluZyBkYXRhIGFuZCB0aGUgZXhwbGFuYXRvcnkgdmFyaWFibGVzIGFyZSB1c2VkIHRvIGVzdGltYXRlIG51bWVyaWMgdmFsdWVzIChpbiB0aGUgY2FzZSBvZiBwcmVkaWN0aW9uKSBvciBjYXRlZ29yaWNhbCB2YWx1ZXMgKGluIHRoZSBjYXNlIG9mIGNsYXNzaWZpY2F0aW9uKSBvZiB0aGUgb3V0Y29tZSB2YXJpYWJsZSBvZiBpbnRlcmVzdC4gV2UgbGVhcm5lZCB0aGF0IHdlIHNwZWNpZnkgdGhlIG1vZGVsIGFuZCBpdHMgc3BlY2lmaWNhdGlvbnMgdXNpbmcgdGhlIGBwYXJuc2lwYCBwYWNrYWdlIGFuZCB0aGF0IHdlIGFsc28gdXNlIHRoaXMgcGFja2FnZSB0byBmaXQgdGhlIG1vZGVsIHVzaW5nIHRoZSBgZml0KClgIGZ1bmN0aW9uLiBXZSBsZWFybmVkIHRoYXQgd2UgaWYganVzdCB1c2UgYHBhcnNuaXBgIHRvIGZpdCB0aGUgbW9kZWwsIHRoZW4gd2UgbmVlZCB0byB1c2UgdGhlIHByZS1wcm9jZXNzZWQgdHJhaW5pbmcgZGF0YSAob3V0cHV0IGZyb20gYGp1aWNlKClgKS4gV2UgbGVhcm5lZCB0aGF0IHdlIGNhbiB1c2UgdGhlIHJhdyB0cmFpbmluZyBkYXRhIGlmIHdlIHVzZSB0aGUgYHdvcmtmbG93c2AgcGFja2FnZSB0byBjcmVhdGUgYSB3b3JrZmxvdyB0aGF0IHByZS1wcm9jZXNzZXMgb3VyIGRhdGEgZm9yIHVzLiAgIAoKV2UgbGVhcm5lZCB0aGF0IGlmIHRoZSBtb2RlbCBmaXRzIHdlbGwgdGhhbiB0aGUgZXN0aW1hdGVkIHZhbHVlcyB3aWxsIGJlIHZlcnkgc2ltaWxhciB0byB0aGUgdHJ1ZSBvdXRjb21lIHZhcmlhYmxlIHZhbHVlcyBpbiBvdXIgdHJhaW5pbmcgZGF0YS4gV2UgbGVhcm5lZCB0aGF0IHdlIGNhbiBhc3Nlc3MgbW9kZWwgcGVyZm9ybWFuY2UgdXNpbmcgdGhlIGB5YXJkc3RpY2tgIHBhY2thZ2Ugd2l0aCB0aGUgYG1ldHJpY3NgIGZ1bmN0aW8gb3IgdGhlIGB0dW5lYCBwYWNrYWdlIGFuZCB0aGUgYGNvbGxlY3RfbWV0cmljcygpYCBmdW5jdGlvbiAocmVxdWlyZWQgaWYgdXNpbmcgY3Jvc3MgdmFsaWRhdGlvbiBvciB0dW5pbmcpLiBXZSBhbHNvIGxlYXJuZWQgdGhhdCB3ZSBjYW4gdXNlIHN1YnNldHMgb2Ygb3VyIHRyYWluaW5nIGRhdGEgKHdoaWNoIHdlIGNyZWF0ZWQgd2l0aCB0aGUgYHJzYW1wbGVgIHBhY2thZ2UpIHRvIHBlcmZvcm0gY3Jvc3MgdmFsaWRhdGlvbiB0byBnZXQgYSBiZXR0ZXIgZXN0aW1hdGUgYWJvdXQgdGhlIHBlcmZvcm1hbmNlIG9mIG91ciBtb2RlbCB1c2luZyBvdXIgdHJhaW5pbmcgZGF0YSwgYXMgd2Ugd2FudCBvdXIgcmVzdWx0cyB0byBiZSBnZW5lcmFsaXphYmxlIGFuZCB0byBwZXJmb3JtIHdlbGwgd2l0aCBvdGhlciBkYXRhLCBub3QganVzdCBvdXIgdHJhaW5pbmcgZGF0YS4gV2UgdXNlZCB0aGUgYGZpdF9yZXNhbXBsZXMoKWAgZnVuY3Rpb24gb2YgdGhlIHR1bmUgcGFja2FnZSB0byBmaXQgb3VyIG1vZGVsIG9uIG91ciBkaWZmZXJlbnQgdHJhaW5pbmcgZGF0YSBzdWJzZXRzIGFuZCB0aGUgYGNvbGxlY3RfbWV0cmljcygpYCBmdW5jdGlvbiAoYWxzbyBvZiB0aGUgYHR1bmVgIHBhY2thZ2UpIHRvIGV2YWx1YXRlIG1vZGVsIHBlcmZvcm1hbmNlIHVzaW5nIHRoZXNlIHN1YnNldHMuICBXZSBhbHNvIGxlYXJuZWQgdGhhdCB3ZSBjYW4gcG90ZW50aWFsbHkgaW1wcm92ZSBtb2RlbCBwZXJmb3JtYW5jZSBieSB0dW5pbmcgYXNwZWN0cyBhYm91dCB0aGUgbW9kZWwgY2FsbGVkIFtoeXBlcnBhcmFtZXRlcnNdKGh0dHBzOi8vbWFjaGluZWxlYXJuaW5nbWFzdGVyeS5jb20vZGlmZmVyZW5jZS1iZXR3ZWVuLWEtcGFyYW1ldGVyLWFuZC1hLWh5cGVycGFyYW1ldGVyLyl7dGFyZ2V0PSJfYmxhbmsifSB0byBkZXRlcm1pbmUgdGhlIGJlc3Qgb3B0aW9uIGZvciBtb2RlbCBwZXJmb3JtYW5jZS4gV2UgbGVhcm5lZCB0aGF0IHdlIGNhbiBkbyB0aGlzIHVzaW5nIHRoZSBgdHVuZWAgYW5kIGBkaWFsc2AgcGFja2FnZXMgYW5kIGV2YWx1YXRpbmcgdGhlIHBlcmZvcm1hbmNlIG9mIG91ciBtb2RlbCB3aXRoIHRoZSBkaWZmZXJlbnQgaHlwZXJwYXJhbWV0ZXIgb3B0aW9ucyBhbmQgb3VyIHRyYWluaW5nIGRhdGEgc3Vic2V0cyB0aGF0IHdlIHVzZWQgZm9yIGNyb3NzIHZhbGlkYXRpb24uIEFmdGVyIHdlIHRlc3RlZCBzZXZlcmFsIGRpZmZlcmVudCBtZXRob2RzIHRvIG1vZGVsIG91ciBkYXRhLCB3ZSBjb21wYXJlZCB0aGVtIHRvIGNob29zZSB0aGUgYmVzdCBwZXJmb3JtaW5nIG1vZGVsIGFzIG91ciBmaW5hbCBtb2RlbC4gIAoKCjUuIE92ZXJhbGwgbW9kZWwgcGVyZm9ybWFuY2UgZXZhbHVhdGlvbiAgCgpPbmNlIHdlIGNob3NlIG91ciBmaW5hbCBtb2RlbCwgd2UgZXZhbHVhdGVkIHRoZSBmaW5hbCBtb2RlbCBwZXJmb3JtYW5jZSB1c2luZyB0aGUgdGVzdGluZyBkYXRhIHVzaW5nIHRoZSBgbGFzdF9maXQoKWAgZnVuY3Rpb24gb2YgdGhlIGB0dW5lYCBwYWNrYWdlLiBUaGlzIGdpdmVzIHVzIGEgYmV0dGVyIGVzdGltYXRlIGFib3V0IGhvdyB3ZWxsIHRoZSBtb2RlbCB3aWxsIHByZWRpY3Qgb3IgY2xhc3NpZnkgdGhlIG91dGNvbWUgdmFyaWFibGUgb2YgaW50ZXJlc3Qgd2l0aCBuZXcgaW5kZXBlbmRlbnQgZGF0YS4gSWRlYWxseSBvbmUgd291bGQgYWxzbyBwZXJmb3JtIGFuIGV2YWx1YXRpb24gd2l0aCBpbmRlcGVuZGVudCBkYXRhIHRvIHByb3ZpZGUgYSBzZW5zZSBvZiBob3cgZ2VuZXJhbGl6YWJsZSB0aGUgbW9kZWwgaXMgdG8gb3RoZXIgZGF0YSBzb3VyY2VzLiAKCldlIGFsc28gc2F3IHRoYXQgd2UgY2FuIHVzZSB0aGUgYGNvbGxlY3RfcHJlZGljdGlvbnMoKWAgZnVuY3Rpb24gb2YgdGhlIGB0dW5lYCBwYWNrYWdlIHRvIGdldCB0aGUgcHJlZGljdGlvbnMgZm9yIG91ciB0ZXN0IGRhdGEuIFdlIHNhdyB0aGF0IHdlIGNhbiBnZXQgbW9yZSBkZXRhaWxlZCBwcmVkaWN0aW9uIGRhdGEgdXNpbmcgdGhlIGBwcmVkaWN0KClgIGZ1bmN0aW9uIG9mIHRoZSBgcGFyc25pcGAgcGFja2FnZS4KCjwvZGV0YWlscz4KCgoKIyMgU3VnZ2VzdGVkIEhvbWV3b3JrCgpTdHVkZW50cyBjYW4gcHJlZGljdCBhaXIgcG9sbHV0aW9uIG1vbml0b3IgdmFsdWVzIHVzaW5nIGEgZGlmZmVyZW50IGFsZ29yaXRobSBhbmQgcHJvdmlkZSBhbiBleHBsYW5hdGlvbiBmb3IgaG93IHRoYXQgYWxnb3JpdGhtIHdvcmtzIGFuZCB3aHkgaXQgbWF5IGJlIGEgZ29vZCBjaG9pY2UgZm9yIG1vZGVsaW5nIHRoaXMgZGF0YS4KCgojICoqQWRkaXRpb25hbCBJbmZvcm1hdGlvbioqCioqKgoKIyMgSGVscGZ1bCBMaW5rcwoKMS4gQSByZXZpZXcgb2YgW3RpZHltb2RlbHNdKGh0dHBzOi8vcnZpZXdzLnJzdHVkaW8uY29tLzIwMTkvMDYvMTkvYS1nZW50bGUtaW50cm8tdG8tdGlkeW1vZGVscy8pe3RhcmdldD0iX2JsYW5rIn0gIAoyLiBBIFtjb3Vyc2Ugb24gdGlkeW1vZGVsc10oaHR0cHM6Ly9qdWxpYXNpbGdlLmNvbS9ibG9nL3RpZHltb2RlbHMtbWwtY291cnNlLyl7dGFyZ2V0PSJfYmxhbmsifSBieSBKdWxpYSBTaWxnZSAgCjMuIFtNb3JlIGV4YW1wbGVzLCBleHBsYW5hdGlvbnMsIGFuZCBpbmZvIGFib3V0IHRpZHltb2RlbHMgZGV2ZWxvcG1lbnRdKGh0dHBzOi8vd3d3LnRpZHltb2RlbHMub3JnL2xlYXJuLyl7dGFyZ2V0PSJfYmxhbmsifSBmcm9tIHRoZSBkZXZlbG9wZXJzICAKNC4gQSBndWlkZSBmb3IgW3ByZS1wcm9jZXNzaW5nIHdpdGggcmVjaXBlc10oaHR0cDovL3d3dy5yZWJlY2NhYmFydGVyLmNvbS9ibG9nLzIwMTktMDYtMDZfcHJlX3Byb2Nlc3NpbmcvKXt0YXJnZXQ9Il9ibGFuayJ9ICAKNS4gQSBbZ3VpZGVdKGh0dHBzOi8vYnJpYXR0ZS5naXRodWIuaW8vZ2djb3JyLyl7dGFyZ2V0PSJfYmxhbmsifSBmb3IgdXNpbmcgR0dhbGx5IHRvIGNyZWF0ZSBjb3JyZWxhdGlvbiBwbG90cyAgCjYuIEEgW2d1aWRlXShodHRwczovL3d3dy50aWR5dmVyc2Uub3JnL2Jsb2cvMjAxOC8xMS9wYXJzbmlwLTAtMC0xLyl7dGFyZ2V0PSJfYmxhbmsifSBmb3IgdXNpbmcgcGFyc25pcCB0byB0cnkgZGlmZmVyZW50IGFsZ29yaXRobXMgb3IgZW5naW5lcyAgCjcuIEEgW2xpc3Qgb2YgcmVjaXBlIGZ1bmN0aW9uc10oaHR0cHM6Ly90aWR5bW9kZWxzLmdpdGh1Yi5pby9yZWNpcGVzL3JlZmVyZW5jZS9pbmRleC5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9ICAKOC4gQSBncmVhdCBibG9nIHBvc3QgYWJvdXQgW2Nyb3NzIHZhbGlkYXRpb25dKGh0dHBzOi8vdG93YXJkc2RhdGFzY2llbmNlLmNvbS90cmFpbi10ZXN0LXNwbGl0LWFuZC1jcm9zcy12YWxpZGF0aW9uLWluLXB5dGhvbi04MGI2MWJlY2E0YjYpe3RhcmdldD0iX2JsYW5rIn0gIAo5LiBBIGRpc2N1c3Npb24gYWJvdXQgW2V2YWx1YXRpbmcgbW9kZWwgcGVyZm9ybWFuY2VdKGh0dHBzOi8vbWVkaXVtLmNvbS9AbGltYXZhbGxhbnRpbi9tZXRyaWNzLXRvLW1lYXN1cmUtbWFjaGluZS1sZWFybmluZy1tb2RlbC1wZXJmb3JtYW5jZS1lOGM5NjM2NjU0NzYpe3RhcmdldD0iX2JsYW5rIn0gZm9yIGEgZGVlcGVyIGV4cGxhbmF0aW9uIGFib3V0IGhvdyB0byBldmFsdWF0ZSBtb2RlbCBwZXJmb3JtYW5jZSAgCjEwLiBbUlN0dWRpbyBjaGVhdHNoZWV0c10oaHR0cHM6Ly9yc3R1ZGlvLmNvbS9yZXNvdXJjZXMvY2hlYXRzaGVldHMvKXt0YXJnZXQ9Il9ibGFuayJ9CjExLiBBbiBbZXhwbGFuYXRpb25dKGh0dHBzOi8vdG93YXJkc2RhdGFzY2llbmNlLmNvbS9zdXBlcnZpc2VkLXZzLXVuc3VwZXJ2aXNlZC1sZWFybmluZy0xNGY2OGUzMmVhOGQpe3RhcmdldD0iX2JsYW5rIn0gb2Ygc3VwZXJ2aXNlZCB2cyB1bnN1cGVydmlzZWQgbWFjaGluZSBsZWFybmluZyBhbmQgYmlhcy12YXJpYW5jZSB0cmFkZS1vZmYuCjEyLiBBIHRob3JvdWdoIFtleHBsYW5hdGlvbl0oaHR0cHM6Ly9yb3lhbHNvY2lldHlwdWJsaXNoaW5nLm9yZy9kb2kvMTAuMTA5OC9yc3RhLjIwMTUuMDIwMiM6fjp0ZXh0PVByaW5jaXBhbCUyMGNvbXBvbmVudCUyMGFuYWx5c2lzJTIwKFBDQSklMjBpcyx2YXJpYWJsZXMlMjB0aGF0JTIwc3VjY2Vzc2l2ZWx5JTIwbWF4aW1pemUlMjB2YXJpYW5jZS4pe3RhcmdldD0iX2JsYW5rIn0gb2YgcHJpbmNpcGFsIGNvbXBvbmVudCBhbmFseXNpcy4KMTMuIElmIHlvdSBoYXZlIGFjY2VzcywgdGhpcyBpcyBhIGdyZWF0IFtkaXNjdXNzaW9uXShodHRwczovL3d3dy50YW5kZm9ubGluZS5jb20vZG9pL2Ficy8xMC4xMDgwLzAwMDMxMzA1LjE5ODQuMTA0ODMxODMpe3RhcmdldD0iX2JsYW5rIn0gIGFib3V0IHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gaW5kZXBlbmRlbmNlLCBvcnRob2dvbmFsaXR5LCBhbmQgbGFjayBvZiBjb3JyZWxhdGlvbi4KMTQuIEdyZWF0IFt2aWRlbyBleHBsYW5hdGlvbl0oaHR0cHM6Ly95b3V0dS5iZS9fVVZIbmVCVUJXMCl7dGFyZ2V0PSJfYmxhbmsifSBvZiBQQ0EuICAKCjx1PlRlcm1zIGFuZCBjb25jZXB0cyBjb3ZlcmVkOjwvdT4gIAoKW1RpZHl2ZXJzZV0oaHR0cHM6Ly93d3cudGlkeXZlcnNlLm9yZy8pe3RhcmdldD0iX2JsYW5rIn0gIApbSW1wdXRhdGlvbl0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSW1wdXRhdGlvbl8oc3RhdGlzdGljcykpe3RhcmdldD0iX2JsYW5rIn0gIApbVHJhbnNmb3JtYXRpb25dKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0RhdGFfdHJhbnNmb3JtYXRpb25fKHN0YXRpc3RpY3MpKXt0YXJnZXQ9Il9ibGFuayJ9ICAKW0Rpc2NyZXRpemF0aW9uXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9EaXNjcmV0aXphdGlvbl9vZl9jb250aW51b3VzX2ZlYXR1cmVzKXt0YXJnZXQ9Il9ibGFuayJ9ICAKW0R1bW15IFZhcmlhYmxlc10oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRHVtbXlfdmFyaWFibGVfKHN0YXRpc3RpY3MpKXt0YXJnZXQ9Il9ibGFuayJ9ICAKW09uZSBIb3QgRW5jb2RpbmddKGh0dHBzOi8vbWFjaGluZWxlYXJuaW5nbWFzdGVyeS5jb20vd2h5LW9uZS1ob3QtZW5jb2RlLWRhdGEtaW4tbWFjaGluZS1sZWFybmluZy8pe3RhcmdldD0iX2JsYW5rIn0gIApbRGF0YSBUeXBlIENvbnZlcnNpb25zXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvaGFibGFyL3ZpZ25ldHRlcy9jb252ZXJ0Lmh0bWwpe3RhcmdldD0iX2JsYW5rIn0gIApbSW50ZXJhY3Rpb25dKGh0dHBzOi8vc3RhdGlzdGljc2J5amltLmNvbS9yZWdyZXNzaW9uL2ludGVyYWN0aW9uLWVmZmVjdHMvKXt0YXJnZXQ9Il9ibGFuayJ9ICAKW05vcm1hbGl6YXRpb25dKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL05vcm1hbGl6YXRpb25fKHN0YXRpc3RpY3MpKXt0YXJnZXQ9Il9ibGFuayJ9ICAKW0RpbWVuc2lvbmFsaXR5IFJlZHVjdGlvbi9TaWduYWwgRXh0cmFjdGlvbl0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRGltZW5zaW9uYWxpdHlfcmVkdWN0aW9uKXt0YXJnZXQ9Il9ibGFuayJ9ICAKW1JvdyBPcGVyYXRpb25zXShodHRwczovL3RhcnRhcnVzLm9yZy9nYXJldGgvbWF0aHMvTGluZWFyX0FsZ2VicmEvcm93X29wZXJhdGlvbnMucGRmKXt0YXJnZXQ9Il9ibGFuayJ9ICAKW05lYXIgWmVybyBWYXJhaW5jZV0oaHR0cHM6Ly93d3cuci1ibG9nZ2Vycy5jb20vbmVhci16ZXJvLXZhcmlhbmNlLXByZWRpY3RvcnMtc2hvdWxkLXdlLXJlbW92ZS10aGVtLyl7dGFyZ2V0PSJfYmxhbmsifSAgCltQYXJhbWV0ZXJzIGFuZCBIeXBlcnBhcmFtZXRlcnNdKGh0dHBzOi8vbWFjaGluZWxlYXJuaW5nbWFzdGVyeS5jb20vZGlmZmVyZW5jZS1iZXR3ZWVuLWEtcGFyYW1ldGVyLWFuZC1hLWh5cGVycGFyYW1ldGVyLyl7dGFyZ2V0PSJfYmxhbmsifSAgIApbU3VwZXJ2aXNlZCBhbmQgVW5zcGVydmlzZWQgTGVhcm5pbmddKGh0dHBzOi8vdG93YXJkc2RhdGFzY2llbmNlLmNvbS9zdXBlcnZpc2VkLXZzLXVuc3VwZXJ2aXNlZC1sZWFybmluZy0xNGY2OGUzMmVhOGQpe3RhcmdldD0iX2JsYW5rIn0gIApbUHJpbmNpcGFsIENvbXBvbmVudCBBbmFseXNpc10oaHR0cHM6Ly9tZWRpdW0uY29tL0BzYXZhc3RhbWlya28vcGNhLWEtbGluZWFyLXRyYW5zZm9ybWF0aW9uLWY4YWFjZDRlYjAwNyl7dGFyZ2V0PSJfYmxhbmsifSAgCltMaW5lYXIgQ29tYmluYXRpb25zXShodHRwczovL3d3dy5tYXRoYm9vdGNhbXBzLmNvbS9saW5lYXItY29tYmluYXRpb25zLXZlY3RvcnMvKXt0YXJnZXQ9Il9ibGFuayJ9ICAKW0RlY2lzaW9uIFRyZWVdKGh0dHBzOi8vbWVkaXVtLmNvbS9ncmV5YXRvbS9kZWNpc2lvbi10cmVlcy1hLXNpbXBsZS13YXktdG8tdmlzdWFsaXplLWEtZGVjaXNpb24tZGM1MDZhNDAzYWViKXt0YXJnZXQ9Il9ibGFuayJ9ICAKW1JhbmRvbSBGb3Jlc3RdKGh0dHBzOi8vdG93YXJkc2RhdGFzY2llbmNlLmNvbS9kZWNpc2lvbi10cmVlLWVuc2VtYmxlcy1iYWdnaW5nLWFuZC1ib29zdGluZy0yNjZhOGJhNjBmZDkpe3RhcmdldD0iX2JsYW5rIn0gIAoKCjx1PlBhY2thZ2VzIHVzZWQgaW4gdGhpcyBjYXNlIHN0dWR5OiA8L3U+CgogUGFja2FnZSAgIHwgVXNlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAotLS0tLS0tLS0tIHwtLS0tLS0tLS0tLS0tCltoZXJlXShodHRwczovL2dpdGh1Yi5jb20vamVubnliYy9oZXJlX2hlcmUpe3RhcmdldD0iX2JsYW5rIn0gICAgICAgfCB0byBlYXNpbHkgbG9hZCBhbmQgc2F2ZSBkYXRhCltyZWFkcl0oaHR0cHM6Ly9yZWFkci50aWR5dmVyc2Uub3JnLyl7dGFyZ2V0PSJfYmxhbmsifSAgICAgIHwgdG8gaW1wb3J0IHRoZSBDU1YgZmlsZSBkYXRhCltkcGx5cl0oaHR0cHM6Ly9kcGx5ci50aWR5dmVyc2Uub3JnLyl7dGFyZ2V0PSJfYmxhbmsifSAgICAgIHwgdG8gdmlldy9hcnJhbmdlL2ZpbHRlci9zZWxlY3QvY29tcGFyZSBzcGVjaWZpYyBzdWJzZXRzIG9mIHRoZSBkYXRhIApbc2tpbXJdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9za2ltci9pbmRleC5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9ICAgICAgfCB0byBnZXQgYW4gb3ZlcnZpZXcgb2YgZGF0YQpbc3VtbWFyeXRvb2xzXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvc2tpbXIvaW5kZXguaHRtbCl7dGFyZ2V0PSJfYmxhbmsifSAgICAgIHwgdG8gZ2V0IGFuIG92ZXJ2aWV3IG9mIGRhdGEgaW4gYSBkaWZmZXJlbnQgc3R5bGUKW21hZ3JpdHRyXShodHRwczovL21hZ3JpdHRyLnRpZHl2ZXJzZS5vcmcvYXJ0aWNsZXMvbWFncml0dHIuaHRtbCl7dGFyZ2V0PSJfYmxhbmsifSAgIHwgdG8gdXNlIHRoZSBgJTw+JWAgcGlwcGluZyBvcGVyYXRvciAKW2NvcnJwbG90XShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvY29ycnBsb3QvdmlnbmV0dGVzL2NvcnJwbG90LWludHJvLmh0bWwpe3RhcmdldD0iX2JsYW5rIn0gfCB0byBtYWtlIGxhcmdlIGNvcnJlbGF0aW9uIHBsb3RzCltHR2FsbHldKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9HR2FsbHkvR0dhbGx5LnBkZil7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIG1ha2Ugc21hbGxlciBjb3JyZWxhdGlvbiBwbG90cyAgCltyc2FtcGxlXShodHRwczovL3RpZHltb2RlbHMuZ2l0aHViLmlvL3JzYW1wbGUvYXJ0aWNsZXMvQmFzaWNzLmh0bWwpe3RhcmdldD0iX2JsYW5rIn0gICB8IHRvIHNwbGl0IHRoZSBkYXRhIGludG8gdGVzdGluZyBhbmQgdHJhaW5pbmcgc2V0cyBhbmQgdG8gc3BsaXQgdGhlIHRyYWluaW5nIHNldCBmb3IgY3Jvc3MtdmFsaWRhdGlvbiAgCltyZWNpcGVzXShodHRwczovL3RpZHltb2RlbHMuZ2l0aHViLmlvL3JlY2lwZXMvKXt0YXJnZXQ9Il9ibGFuayJ9ICAgfCB0byBwcmUtcHJvY2VzcyBkYXRhIGZvciBtb2RlbGluZyBpbiBhIHRpZHkgYW5kIHJlcHJvZHVjaWJsZSB3YXkgYW5kIHRvIGV4dHJhY3QgcHJlLXByb2Nlc3NlZCBkYXRhIChtYWpvciBmdW5jdGlvbnMgYXJlIGByZWNpcGUoKWAgLCBgcHJlcCgpYCBhbmQgdmFyaW91cyB0cmFuc2Zvcm1hdGlvbiBgc3RlcF8qKClgIGZ1bmN0aW9ucywgYXMgd2VsbCBhcyBganVpY2UoKWAgLSBleHRyYWN0cyBmaW5hbCBwcmUtcHJvY2Vzc2VkIHRyYWluaW5nIGRhdGEgYW5kIGBiYWtlKClgIC0gYXBwbGllcyByZWNpcGUgc3RlcHMgdG8gdGVzdGluZyBkYXRhKS4gU2VlIFtoZXJlXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvcmVjaXBlcy9yZWNpcGVzLnBkZil7dGFyZ2V0PSJfYmxhbmsifSAgZm9yIG1vcmUgaW5mby4KW3BhcnNuaXBdKGh0dHBzOi8vdGlkeW1vZGVscy5naXRodWIuaW8vcGFyc25pcC8pe3RhcmdldD0iX2JsYW5rIn0gICB8IGFuIGludGVyZmFjZSB0byBjcmVhdGUgbW9kZWxzIChtYWpvciBmdW5jdGlvbnMgYXJlICBgZml0KClgLCBgc2V0X2VuZ2luZSgpYCkKW3lhcmRzdGlja10oaHR0cHM6Ly90aWR5bW9kZWxzLmdpdGh1Yi5pby95YXJkc3RpY2svKXt0YXJnZXQ9Il9ibGFuayJ9ICAgfCB0byBldmFsdWF0ZSB0aGUgcGVyZm9ybWFuY2Ugb2YgbW9kZWxzClticm9vbV0oaHR0cHM6Ly93d3cudGlkeXZlcnNlLm9yZy9ibG9nLzIwMTgvMDcvYnJvb20tMC01LTAvKXt0YXJnZXQ9Il9ibGFuayJ9IHwgdG8gZ2V0IHRpZHkgb3V0cHV0IGZvciBvdXIgbW9kZWwgZml0IGFuZCBwZXJmb3JtYW5jZQpbZ2dwbG90Ml0oaHR0cHM6Ly9nZ3Bsb3QyLnRpZHl2ZXJzZS5vcmcvKXt0YXJnZXQ9Il9ibGFuayJ9ICAgIHwgdG8gbWFrZSB2aXN1YWxpemF0aW9ucyB3aXRoIG11bHRpcGxlIGxheWVycwpbZGlhbHNdKGh0dHBzOi8vd3d3LnRpZHl2ZXJzZS5vcmcvYmxvZy8yMDE5LzEwL2RpYWxzLTAtMC0zLyl7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIHNwZWNpZnkgaHlwZXItcGFyYW1ldGVyIHR1bmluZwpbdHVuZV0oaHR0cHM6Ly90dW5lLnRpZHltb2RlbHMub3JnLyl7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIHBlcmZvcm0gY3Jvc3MgdmFsaWRhdGlvbiwgdHVuZSBoeXBlci1wYXJhbWV0ZXJzLCBhbmQgZ2V0IHBlcmZvcm1hbmNlIG1ldHJpY3MKW3dvcmtmbG93c10oaHR0cHM6Ly93d3cucmRvY3VtZW50YXRpb24ub3JnL3BhY2thZ2VzL3dvcmtmbG93cy92ZXJzaW9ucy8wLjEuMSl7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIGNyZWF0ZSBtb2RlbGluZyB3b3JrZmxvdyB0byBzdHJlYW1saW5lIHRoZSBtb2RlbGluZyBwcm9jZXNzClt2aXBdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy92aXAvdmlwLnBkZil7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIGNyZWF0ZSB2YXJpYWJsZSBpbXBvcnRhbmNlIHBsb3RzCltyYW5kb21Gb3Jlc3RdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9yYW5kb21Gb3Jlc3QvcmFuZG9tRm9yZXN0LnBkZil7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIHBlcmZvcm0gdGhlIHJhbmRvbSBmb3Jlc3QgYW5hbHlzaXMKW3N0cmluZ3JdKGh0dHBzOi8vc3RyaW5nci50aWR5dmVyc2Uub3JnL2FydGljbGVzL3N0cmluZ3IuaHRtbCl7dGFyZ2V0PSJfYmxhbmsifSAgICB8IHRvIG1hbmlwdWxhdGUgdGhlIHRleHQgdGhlIG1hcCBkYXRhClt0aWR5cl0oaHR0cHM6Ly90aWR5ci50aWR5dmVyc2Uub3JnLyl7dGFyZ2V0PSJfYmxhbmsifSAgICAgIHwgdG8gc2VwYXJhdGUgZGF0YSB3aXRoaW4gYSBjb2x1bW4gaW50byBtdWx0aXBsZSBjb2x1bW5zCltybmF0dXJhbGVhcnRoXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvcm5hdHVyYWxlYXJ0aC9SRUFETUUuaHRtbCl7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIGdldCB0aGUgZ2VvbWV0cnkgZGF0YSBmb3IgdGhlIGVhcnRoIHRvIHBsb3QgdGhlIFVTClttYXBzXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvbWFwcy9tYXBzLnBkZil7dGFyZ2V0PSJfYmxhbmsifSB8IHRvIGdldCBtYXAgZGF0YWJhc2UgZGF0YSBhYm91dCBjb3VudGllcyB0byBkcmF3IHRoZW0gb24gb3VyIFVTIG1hcApbc2ZdKGh0dHBzOi8vci1zcGF0aWFsLmdpdGh1Yi5pby9zZi8pe3RhcmdldD0iX2JsYW5rIn0gIHwgdG8gY29udmVydCB0aGUgbWFwIGRhdGEgaW50byBhIGRhdGEgZnJhbWUKW2x3Z2VvbV0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL2x3Z2VvbS9sd2dlb20ucGRmKXt0YXJnZXQ9Il9ibGFuayJ9IHwgdG8gdXNlIHRoZSBgc2ZgIGZ1bmN0aW9uIHRvIGNvbnZlcnQgdGhlIG1hcCBnZW9ncmFwaGljYWwgZGF0YQpbcmdlb3NdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9yZ2Vvcy9yZ2Vvcy5wZGYpe3RhcmdldD0iX2JsYW5rIn0gfCB0byB1c2UgZ2VvbWV0cnkgZGF0YQpbcGF0Y2h3b3JrXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvcGF0Y2h3b3JrL3BhdGNod29yay5wZGYpe3RhcmdldD0iX2JsYW5rIn0gfCB0byBhbGxvdyBwbG90cyB0byBiZSBjb21iaW5lZAoKCiMjIFNlc3Npb24gaW5mbyAKCgpgYGB7cn0Kc2Vzc2lvbkluZm8oKQpgYGAKCgojIyBBY2tub3dsZWRnZW1lbnRzCgoKV2Ugd291bGQgbGlrZSB0byBhY2tub3dsZWRnZSBbUm9nZXIgUGVuZ10oaHR0cDovL3d3dy5iaW9zdGF0Lmpoc3BoLmVkdS9+cnBlbmcvKSwgW01lZ2FuIExhdHNoYXddKGh0dHBzOi8vd3d3Lmpoc3BoLmVkdS9mYWN1bHR5L2RpcmVjdG9yeS9wcm9maWxlLzE3MDgvbWVnYW4td2VpbC1sYXRzaGF3KSwgYW5kIFtLcmlzdGVuIEtvZWhsZXJdKGh0dHBzOi8vd3d3Lmpoc3BoLmVkdS9mYWN1bHR5L2RpcmVjdG9yeS9wcm9maWxlLzI5Mjgva2lyc3Rlbi1rb2VobGVyKWZvciBhc3Npc3RpbmcgaW4gZnJhbWluZyB0aGUgbWFqb3IgZGlyZWN0aW9uIG9mIHRoZSBjYXNlIHN0dWR5LgoKV2Ugd291bGQgYWxzbyBsaWtlIHRvIGFja25vd2xlZGdlIHRoZSBbQmxvb21iZXJnIEFtZXJpY2FuIEhlYWx0aCBJbml0aWF0aXZlXShodHRwczovL2FtZXJpY2FuaGVhbHRoLmpodS5lZHUvKSBmb3IgZnVuZGluZyB0aGlzIHdvcmsuIAo=